mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
x86: sbrdsp: implement SSE2 hf_apply_noise
233 to 105 cycles on Arrandale and Win64. Replacing the multiplication by s_m[m] by a pand and a pxor with appropriate vectors is slower. Unrolling is a 15 cycles win. A SSE version was 4 cycles slower. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
380cfce2b2
commit
76c7277385
@ -352,7 +352,7 @@ static DECLARE_ALIGNED(32, float, sbr_qmf_window_us)[640] = {
|
|||||||
0.8537385600,
|
0.8537385600,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* First two entries repeated at end to simplify SIMD implementations. */
|
/* First eight entries repeated at end to simplify SIMD implementations. */
|
||||||
const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = {
|
const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = {
|
||||||
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
||||||
{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647},
|
{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647},
|
||||||
@ -610,7 +610,11 @@ const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = {
|
|||||||
{-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280},
|
{-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280},
|
||||||
{ 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512},
|
{ 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512},
|
||||||
{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781},
|
{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781},
|
||||||
|
// Start of duplicated table
|
||||||
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
||||||
|
{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647},
|
||||||
|
{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087},
|
||||||
|
{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034},
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* AVCODEC_AACSBRDATA_H */
|
#endif /* AVCODEC_AACSBRDATA_H */
|
||||||
|
@ -26,6 +26,12 @@ SECTION_RODATA
|
|||||||
ps_mask times 2 dd 1<<31, 0
|
ps_mask times 2 dd 1<<31, 0
|
||||||
ps_mask2 times 2 dd 0, 1<<31
|
ps_mask2 times 2 dd 0, 1<<31
|
||||||
ps_neg times 4 dd 1<<31
|
ps_neg times 4 dd 1<<31
|
||||||
|
ps_noise0 times 2 dd 1.0, 0.0,
|
||||||
|
ps_noise2 times 2 dd -1.0, 0.0
|
||||||
|
ps_noise13 dd 0.0, 1.0, 0.0, -1.0
|
||||||
|
dd 0.0, -1.0, 0.0, 1.0
|
||||||
|
dd 0.0, 1.0, 0.0, -1.0
|
||||||
|
cextern sbr_noise_table
|
||||||
|
|
||||||
SECTION_TEXT
|
SECTION_TEXT
|
||||||
|
|
||||||
@ -314,3 +320,111 @@ cglobal sbr_qmf_pre_shuffle, 1,4,7,z
|
|||||||
mova m2, [zq]
|
mova m2, [zq]
|
||||||
movq [r2q], m2
|
movq [r2q], m2
|
||||||
REP_RET
|
REP_RET
|
||||||
|
|
||||||
|
%if WIN64
|
||||||
|
%define NREGS 0
|
||||||
|
%define NOISE_TABLE sbr_noise_table
|
||||||
|
%else
|
||||||
|
%ifdef PIC
|
||||||
|
%define NREGS 1
|
||||||
|
%if UNIX64
|
||||||
|
%define NOISE_TABLE r6q ; r5q is m_max
|
||||||
|
%else
|
||||||
|
%define NOISE_TABLE r5q
|
||||||
|
%endif
|
||||||
|
%else
|
||||||
|
%define NREGS 0
|
||||||
|
%define NOISE_TABLE sbr_noise_table
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%macro LOAD_NST 1
|
||||||
|
%if NREGS
|
||||||
|
lea NOISE_TABLE, [%1]
|
||||||
|
mova m0, [kxq + NOISE_TABLE]
|
||||||
|
%else
|
||||||
|
mova m0, [kxq + %1]
|
||||||
|
%endif
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
INIT_XMM sse2
|
||||||
|
; sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m,
|
||||||
|
; const float *q_filt, int noise,
|
||||||
|
; int kx, int m_max)
|
||||||
|
cglobal sbr_hf_apply_noise_0, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max
|
||||||
|
mova m0, [ps_noise0]
|
||||||
|
jmp apply_noise_main
|
||||||
|
|
||||||
|
; sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m,
|
||||||
|
; const float *q_filt, int noise,
|
||||||
|
; int kx, int m_max)
|
||||||
|
cglobal sbr_hf_apply_noise_1, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max
|
||||||
|
and kxq, 1
|
||||||
|
shl kxq, 4
|
||||||
|
LOAD_NST ps_noise13
|
||||||
|
jmp apply_noise_main
|
||||||
|
|
||||||
|
; sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m,
|
||||||
|
; const float *q_filt, int noise,
|
||||||
|
; int kx, int m_max)
|
||||||
|
cglobal sbr_hf_apply_noise_2, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max
|
||||||
|
mova m0, [ps_noise2]
|
||||||
|
jmp apply_noise_main
|
||||||
|
|
||||||
|
; sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m,
|
||||||
|
; const float *q_filt, int noise,
|
||||||
|
; int kx, int m_max)
|
||||||
|
cglobal sbr_hf_apply_noise_3, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max
|
||||||
|
and kxq, 1
|
||||||
|
shl kxq, 4
|
||||||
|
LOAD_NST ps_noise13+16
|
||||||
|
|
||||||
|
apply_noise_main:
|
||||||
|
%if ARCH_X86_64 == 0 || WIN64
|
||||||
|
mov kxd, m_maxm
|
||||||
|
%define count kxq
|
||||||
|
%else
|
||||||
|
%define count m_maxq
|
||||||
|
%endif
|
||||||
|
dec noiseq
|
||||||
|
shl count, 2
|
||||||
|
%if NREGS
|
||||||
|
lea NOISE_TABLE, [sbr_noise_table]
|
||||||
|
%endif
|
||||||
|
lea Yq, [Yq + 2*count]
|
||||||
|
add s_mq, count
|
||||||
|
add q_filtq, count
|
||||||
|
shl noiseq, 3
|
||||||
|
pxor m5, m5
|
||||||
|
neg count
|
||||||
|
.loop:
|
||||||
|
mova m1, [q_filtq + count]
|
||||||
|
movu m3, [noiseq + NOISE_TABLE + 1*mmsize]
|
||||||
|
movu m4, [noiseq + NOISE_TABLE + 2*mmsize]
|
||||||
|
add noiseq, 2*mmsize
|
||||||
|
and noiseq, 0x1ff<<3
|
||||||
|
punpckhdq m2, m1, m1
|
||||||
|
punpckldq m1, m1
|
||||||
|
mulps m1, m3 ; m2 = q_filt[m] * ff_sbr_noise_table[noise]
|
||||||
|
mulps m2, m4 ; m2 = q_filt[m] * ff_sbr_noise_table[noise]
|
||||||
|
mova m3, [s_mq + count]
|
||||||
|
; TODO: replace by a vpermd in AVX2
|
||||||
|
punpckhdq m4, m3, m3
|
||||||
|
punpckldq m3, m3
|
||||||
|
pcmpeqd m6, m3, m5 ; m6 == 0
|
||||||
|
pcmpeqd m7, m4, m5 ; m7 == 0
|
||||||
|
mulps m3, m0 ; s_m[m] * phi_sign
|
||||||
|
mulps m4, m0 ; s_m[m] * phi_sign
|
||||||
|
pand m1, m6
|
||||||
|
pand m2, m7
|
||||||
|
movu m6, [Yq + 2*count]
|
||||||
|
movu m7, [Yq + 2*count + mmsize]
|
||||||
|
addps m3, m1
|
||||||
|
addps m4, m2
|
||||||
|
addps m6, m3
|
||||||
|
addps m7, m4
|
||||||
|
movu [Yq + 2*count], m6
|
||||||
|
movu [Yq + 2*count + mmsize], m7
|
||||||
|
add count, mmsize
|
||||||
|
jl .loop
|
||||||
|
RET
|
||||||
|
@ -38,6 +38,19 @@ void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1);
|
|||||||
void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1);
|
void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1);
|
||||||
void ff_sbr_qmf_pre_shuffle_sse2(float *z);
|
void ff_sbr_qmf_pre_shuffle_sse2(float *z);
|
||||||
|
|
||||||
|
void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m,
|
||||||
|
const float *q_filt, int noise,
|
||||||
|
int kx, int m_max);
|
||||||
|
void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m,
|
||||||
|
const float *q_filt, int noise,
|
||||||
|
int kx, int m_max);
|
||||||
|
void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m,
|
||||||
|
const float *q_filt, int noise,
|
||||||
|
int kx, int m_max);
|
||||||
|
void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m,
|
||||||
|
const float *q_filt, int noise,
|
||||||
|
int kx, int m_max);
|
||||||
|
|
||||||
av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
|
av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
|
||||||
{
|
{
|
||||||
int mm_flags = av_get_cpu_flags();
|
int mm_flags = av_get_cpu_flags();
|
||||||
@ -55,5 +68,9 @@ av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
|
|||||||
if (EXTERNAL_SSE2(mm_flags)) {
|
if (EXTERNAL_SSE2(mm_flags)) {
|
||||||
s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2;
|
s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2;
|
||||||
s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2;
|
s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2;
|
||||||
|
s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2;
|
||||||
|
s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2;
|
||||||
|
s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2;
|
||||||
|
s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user