[x264-devel] commit: Add sad_aligned for faster subme=1 mbcmp (Jason Garrett-Glaser )
git version control
git at videolan.org
Fri Sep 5 22:13:23 CEST 2008
x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Wed Sep 3 15:15:17 2008 -0700| [f6229465eb1307ab7250c8faa350887b7b03598c] | committer: Jason Garrett-Glaser
Add sad_aligned for faster subme=1 mbcmp
Distinguish between unaligned and aligned uses of mbcmp
SAD_aligned, for MMX SADs, uses non-cacheline SADs.
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=f6229465eb1307ab7250c8faa350887b7b03598c
---
common/pixel.c | 35 +++++++++++++++++++++--------------
common/pixel.h | 2 ++
common/x86/pixel.h | 1 +
common/x86/sad-a.asm | 4 +++-
encoder/analyse.c | 2 +-
encoder/encoder.c | 3 ++-
encoder/me.c | 4 ++--
tools/checkasm.c | 1 +
8 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/common/pixel.c b/common/pixel.c
index 27575b5..3e28d85 100644
--- a/common/pixel.c
+++ b/common/pixel.c
@@ -529,20 +529,24 @@ void x264_pixel_init( int cpu, x264_pixel_function_t *pixf )
{
memset( pixf, 0, sizeof(*pixf) );
-#define INIT2( name, cpu ) \
- pixf->name[PIXEL_16x16] = x264_pixel_##name##_16x16##cpu;\
- pixf->name[PIXEL_16x8] = x264_pixel_##name##_16x8##cpu;
-#define INIT4( name, cpu ) \
- INIT2( name, cpu ) \
- pixf->name[PIXEL_8x16] = x264_pixel_##name##_8x16##cpu;\
- pixf->name[PIXEL_8x8] = x264_pixel_##name##_8x8##cpu;
-#define INIT5( name, cpu ) \
- INIT4( name, cpu ) \
- pixf->name[PIXEL_8x4] = x264_pixel_##name##_8x4##cpu;
-#define INIT7( name, cpu ) \
- INIT5( name, cpu ) \
- pixf->name[PIXEL_4x8] = x264_pixel_##name##_4x8##cpu;\
- pixf->name[PIXEL_4x4] = x264_pixel_##name##_4x4##cpu;
+#define INIT2_NAME( name1, name2, cpu ) \
+ pixf->name1[PIXEL_16x16] = x264_pixel_##name2##_16x16##cpu;\
+ pixf->name1[PIXEL_16x8] = x264_pixel_##name2##_16x8##cpu;
+#define INIT4_NAME( name1, name2, cpu ) \
+ INIT2_NAME( name1, name2, cpu ) \
+ pixf->name1[PIXEL_8x16] = x264_pixel_##name2##_8x16##cpu;\
+ pixf->name1[PIXEL_8x8] = x264_pixel_##name2##_8x8##cpu;
+#define INIT5_NAME( name1, name2, cpu ) \
+ INIT4_NAME( name1, name2, cpu ) \
+ pixf->name1[PIXEL_8x4] = x264_pixel_##name2##_8x4##cpu;
+#define INIT7_NAME( name1, name2, cpu ) \
+ INIT5_NAME( name1, name2, cpu ) \
+ pixf->name1[PIXEL_4x8] = x264_pixel_##name2##_4x8##cpu;\
+ pixf->name1[PIXEL_4x4] = x264_pixel_##name2##_4x4##cpu;
+#define INIT2( name, cpu ) INIT2_NAME( name, name, cpu )
+#define INIT4( name, cpu ) INIT4_NAME( name, name, cpu )
+#define INIT5( name, cpu ) INIT5_NAME( name, name, cpu )
+#define INIT7( name, cpu ) INIT7_NAME( name, name, cpu )
#define INIT_ADS( cpu ) \
pixf->ads[PIXEL_16x16] = x264_pixel_ads4##cpu;\
@@ -550,6 +554,7 @@ void x264_pixel_init( int cpu, x264_pixel_function_t *pixf )
pixf->ads[PIXEL_8x8] = x264_pixel_ads1##cpu;
INIT7( sad, );
+ INIT7_NAME( sad_aligned, sad, );
INIT7( sad_x3, );
INIT7( sad_x4, );
INIT7( ssd, );
@@ -574,6 +579,7 @@ void x264_pixel_init( int cpu, x264_pixel_function_t *pixf )
if( cpu&X264_CPU_MMXEXT )
{
INIT7( sad, _mmxext );
+ INIT7_NAME( sad_aligned, sad, _mmxext );
INIT7( sad_x3, _mmxext );
INIT7( sad_x4, _mmxext );
INIT7( satd, _mmxext );
@@ -640,6 +646,7 @@ void x264_pixel_init( int cpu, x264_pixel_function_t *pixf )
INIT5( satd, _sse2 );
INIT5( satd_x3, _sse2 );
INIT5( satd_x4, _sse2 );
+ INIT2_NAME( sad_aligned, sad, _sse2_aligned );
pixf->var[PIXEL_16x16] = x264_pixel_var_16x16_sse2;
pixf->ssim_4x4x2_core = x264_pixel_ssim_4x4x2_core_sse2;
pixf->ssim_end4 = x264_pixel_ssim_end4_sse2;
diff --git a/common/pixel.h b/common/pixel.h
index fd23680..127f89d 100644
--- a/common/pixel.h
+++ b/common/pixel.h
@@ -69,10 +69,12 @@ typedef struct
x264_pixel_cmp_t ssim[7];
x264_pixel_cmp_t sa8d[4];
x264_pixel_cmp_t mbcmp[7]; /* either satd or sad for subpel refine and mode decision */
+ x264_pixel_cmp_t mbcmp_unaligned[7]; /* unaligned mbcmp for subpel */
x264_pixel_cmp_t fpelcmp[7]; /* either satd or sad for fullpel motion search */
x264_pixel_cmp_x3_t fpelcmp_x3[7];
x264_pixel_cmp_x4_t fpelcmp_x4[7];
x264_pixel_var_t var[4];
+ x264_pixel_cmp_t sad_aligned[7]; /* Aligned SAD for mbcmp */
void (*ssim_4x4x2_core)( const uint8_t *pix1, int stride1,
const uint8_t *pix2, int stride2, int sums[2][4] );
diff --git a/common/x86/pixel.h b/common/x86/pixel.h
index 9326a84..cbb37dd 100644
--- a/common/x86/pixel.h
+++ b/common/x86/pixel.h
@@ -43,6 +43,7 @@
DECL_X1( sad, mmxext )
DECL_X1( sad, sse2 )
DECL_X1( sad, sse3 )
+DECL_X1( sad, sse2_aligned )
DECL_X4( sad, mmxext )
DECL_X4( sad, sse2 )
DECL_X4( sad, sse3 )
diff --git a/common/x86/sad-a.asm b/common/x86/sad-a.asm
index a954500..2c16722 100644
--- a/common/x86/sad-a.asm
+++ b/common/x86/sad-a.asm
@@ -215,7 +215,9 @@ cglobal x264_pixel_sad_16x8_%1, 4,4
SAD_W16 sse2
%define movdqu lddqu
SAD_W16 sse3
-%undef movdqu
+%define movdqu movdqa
+SAD_W16 sse2_aligned
+%define movdqu movups
diff --git a/encoder/analyse.c b/encoder/analyse.c
index cd7f745..d9e77a3 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -588,7 +588,7 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_
if( flags & X264_ANALYSE_I8x8 )
{
DECLARE_ALIGNED_16( uint8_t edge[33] );
- x264_pixel_cmp_t sa8d = (*h->pixf.mbcmp == *h->pixf.sad) ? h->pixf.sad[PIXEL_8x8] : h->pixf.sa8d[PIXEL_8x8];
+ x264_pixel_cmp_t sa8d = (h->pixf.mbcmp[0] == h->pixf.satd[0]) ? h->pixf.sa8d[PIXEL_8x8] : h->pixf.mbcmp[PIXEL_8x8];
int i_satd_thresh = a->b_mbrd ? COST_MAX : X264_MIN( i_satd_inter, a->i_satd_i16x16 );
int i_cost = 0;
b_merged_satd = h->pixf.intra_sa8d_x3_8x8 && h->pixf.mbcmp[0] == h->pixf.satd[0];
diff --git a/encoder/encoder.c b/encoder/encoder.c
index d991a5e..584aef6 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -583,7 +583,8 @@ static int x264_validate_parameters( x264_t *h )
static void mbcmp_init( x264_t *h )
{
int satd = !h->mb.b_lossless && h->param.analyse.i_subpel_refine > 1;
- memcpy( h->pixf.mbcmp, satd ? h->pixf.satd : h->pixf.sad, sizeof(h->pixf.mbcmp) );
+ memcpy( h->pixf.mbcmp, satd ? h->pixf.satd : h->pixf.sad_aligned, sizeof(h->pixf.mbcmp) );
+ memcpy( h->pixf.mbcmp_unaligned, satd ? h->pixf.satd : h->pixf.sad, sizeof(h->pixf.mbcmp_unaligned) );
satd &= h->param.analyse.i_me_method == X264_ME_TESA;
memcpy( h->pixf.fpelcmp, satd ? h->pixf.satd : h->pixf.sad, sizeof(h->pixf.fpelcmp) );
memcpy( h->pixf.fpelcmp_x3, satd ? h->pixf.satd_x3 : h->pixf.sad_x3, sizeof(h->pixf.fpelcmp_x3) );
diff --git a/encoder/me.c b/encoder/me.c
index 285c3fc..34d28ae 100644
--- a/encoder/me.c
+++ b/encoder/me.c
@@ -663,7 +663,7 @@ if( b_refine_qpel || (dir^1) != odir ) \
{ \
int stride = 16; \
uint8_t *src = h->mc.get_ref( pix[0], &stride, m->p_fref, m->i_stride[0], mx, my, bw, bh ); \
- int cost = h->pixf.mbcmp[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ int cost = h->pixf.mbcmp_unaligned[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
if( b_chroma_me && cost < bcost ) \
{ \
@@ -904,7 +904,7 @@ int x264_me_refine_bidir( x264_t *h, x264_me_t *m0, x264_me_t *m1, int i_weight
{ \
int stride = 16; \
uint8_t *src = h->mc.get_ref( pix, &stride, m->p_fref, m->i_stride[0], mx, my, bw*4, bh*4 ); \
- dst = h->pixf.mbcmp[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ dst = h->pixf.mbcmp_unaligned[i_pixel]( m->p_fenc[0], FENC_STRIDE, src, stride ) \
+ p_cost_mvx[mx] + p_cost_mvy[my]; \
COPY1_IF_LT( bsatd, dst ); \
}
diff --git a/tools/checkasm.c b/tools/checkasm.c
index 2ea9271..24f968c 100644
--- a/tools/checkasm.c
+++ b/tools/checkasm.c
@@ -258,6 +258,7 @@ static int check_pixel( int cpu_ref, int cpu_new )
report( "pixel " #name " :" );
TEST_PIXEL( sad, 0 );
+ TEST_PIXEL( sad_aligned, 1 );
TEST_PIXEL( ssd, 1 );
TEST_PIXEL( satd, 0 );
TEST_PIXEL( sa8d, 0 );
More information about the x264-devel
mailing list