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,
|
||||
};
|
||||
|
||||
/* 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] = {
|
||||
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
||||
{ 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.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512},
|
||||
{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781},
|
||||
// Start of duplicated table
|
||||
{-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 */
|
||||
|
@ -26,6 +26,12 @@ SECTION_RODATA
|
||||
ps_mask times 2 dd 1<<31, 0
|
||||
ps_mask2 times 2 dd 0, 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
|
||||
|
||||
@ -314,3 +320,111 @@ cglobal sbr_qmf_pre_shuffle, 1,4,7,z
|
||||
mova m2, [zq]
|
||||
movq [r2q], m2
|
||||
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_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)
|
||||
{
|
||||
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)) {
|
||||
s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_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