📄 xvid_bench.c
字号:
emms(); \ for(q=1; q<=max_Q; ++q) { \ for(tst=0; tst<nb_tests; ++tst) \ (FUNC)((DST), (SRC), q); \ for(i=0; i<64; ++i) s+=(DST)[i]^i^qm; \ } \ emms(); \ } \ t = (gettime_usec()-t-overhead)/nb_tests/qm;\ s = (s&0xffff)^(s>>16)#define TEST_QUANT2(FUNC, DST, SRC) \ t = gettime_usec(); \ for(s=0,qm=1; qm<=255; ++qm) { \ for(i=0; i<8*8; ++i) Quant[i] = qm; \ set_intra_matrix( Quant ); \ emms(); \ for(q=1; q<=max_Q; ++q) { \ for(tst=0; tst<nb_tests; ++tst) \ (FUNC)((DST), (SRC), q, q); \ for(i=0; i<64; ++i) s+=(DST)[i]^i^qm; \ } \ emms(); \ } \ t = (gettime_usec()-t-overhead)/nb_tests/qm;\ s = (s&0xffff)^(s>>16)void test_quant(){ const int nb_tests = 1*speed_ref; const int max_Q = 31; int i, qm; CPU *cpu; int16_t Src[8*8], Dst[8*8]; uint8_t Quant[8*8]; printf( "\n ===== test quant =====\n" ); /* we deliberately enfringe the norm's specified range [-127,127], */ /* to test the robustness of the iquant module */ for(i=0; i<64; ++i) { Src[i] = 1 + (i-32) * (i&6); Dst[i] = 0; } for(cpu = cpu_short_list; cpu->name!=0; ++cpu) { double t, overhead; int tst, q; uint32_t s; if (!init_cpu(cpu)) continue; overhead = -gettime_usec(); for(s=0,qm=1; qm<=255; ++qm) { for(i=0; i<8*8; ++i) Quant[i] = qm; set_inter_matrix( Quant ); for(q=1; q<=max_Q; ++q) for(i=0; i<64; ++i) s+=Dst[i]^i^qm; } overhead += gettime_usec();#if 1 TEST_QUANT2(quant4_intra, Dst, Src); printf( "%s - quant4_intra %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=29809) printf( "*** CRC ERROR! ***\n" ); TEST_QUANT(quant4_inter, Dst, Src); printf( "%s - quant4_inter %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=12574) printf( "*** CRC ERROR! ***\n" );#endif#if 1 TEST_QUANT2(dequant4_intra, Dst, Src); printf( "%s - dequant4_intra %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=24052) printf( "*** CRC ERROR! ***\n" ); TEST_QUANT(dequant4_inter, Dst, Src); printf( "%s - dequant4_inter %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=63847) printf( "*** CRC ERROR! ***\n" );#endif#if 1 TEST_QUANT2(quant_intra, Dst, Src); printf( "%s - quant_intra %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=25662) printf( "*** CRC ERROR! ***\n" ); TEST_QUANT(quant_inter, Dst, Src); printf( "%s - quant_inter %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=23972) printf( "*** CRC ERROR! ***\n" );#endif#if 1 TEST_QUANT2(dequant_intra, Dst, Src); printf( "%s - dequant_intra %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=49900) printf( "*** CRC ERROR! ***\n" ); TEST_QUANT(dequant_inter, Dst, Src); printf( "%s - dequant_inter %.3f usec crc=%d\n", cpu->name, t, s ); if (s!=48899) printf( "*** CRC ERROR! ***\n" );#endif printf( " --- \n" ); }}/********************************************************************* * test non-zero AC counting *********************************************************************/#define TEST_CBP(FUNC, SRC) \ t = gettime_usec(); \ emms(); \ for(tst=0; tst<nb_tests; ++tst) { \ cbp = (FUNC)((SRC)); \ } \ emms(); \ t = (gettime_usec()-t ) / nb_tests;void test_cbp(){ const int nb_tests = 10000*speed_ref; int i; CPU *cpu; int16_t Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64]; printf( "\n ===== test cbp =====\n" ); for(i=0; i<6*64; ++i) { Src1[i] = (i*i*3/8192)&(i/64)&1; /* 'random' */ Src2[i] = (i<3*64); /* half-full */ Src3[i] = ((i+32)>3*64); Src4[i] = (i==(3*64+2) || i==(5*64+9)); } for(cpu = cpu_short_list2; cpu->name!=0; ++cpu) { double t; int tst, cbp; if (!init_cpu(cpu)) continue; TEST_CBP(calc_cbp, Src1); printf( "%s - calc_cbp#1 %.3f usec cbp=0x%x\n", cpu->name, t, cbp ); if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" ); TEST_CBP(calc_cbp, Src2); printf( "%s - calc_cbp#2 %.3f usec cbp=0x%x\n", cpu->name, t, cbp ); if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" ); TEST_CBP(calc_cbp, Src3); printf( "%s - calc_cbp#3 %.3f usec cbp=0x%x\n", cpu->name, t, cbp ); if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" ); TEST_CBP(calc_cbp, Src4); printf( "%s - calc_cbp#4 %.3f usec cbp=0x%x\n", cpu->name, t, cbp ); if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" ); printf( " --- \n" ); }}/********************************************************************* * fdct/idct IEEE1180 compliance *********************************************************************/typedef struct { long Errors[64]; long Sqr_Errors[64]; long Max_Errors[64]; long Nb;} STATS_8x8;void init_stats(STATS_8x8 *S){ int i; for(i=0; i<64; ++i) { S->Errors[i] = 0; S->Sqr_Errors[i] = 0; S->Max_Errors[i] = 0; } S->Nb = 0;}void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64]){ int i; for(i=0; i<64; ++i) { short Err = Blk[i] - Ref[i]; S->Errors[i] += Err; S->Sqr_Errors[i] += Err * Err; if (Err<0) Err = -Err; if (S->Max_Errors[i]<Err) S->Max_Errors[i] = Err; } S->Nb++;}void print_stats(STATS_8x8 *S){ int i; double Norm; assert(S->Nb>0); Norm = 1. / (double)S->Nb; printf("\n== Max absolute values of errors ==\n"); for(i=0; i<64; i++) { printf(" %4ld", S->Max_Errors[i]); if ((i&7)==7) printf("\n"); } printf("\n== Mean square errors ==\n"); for(i=0; i<64; i++) { double Err = Norm * (double)S->Sqr_Errors[i]; printf(" %.3f", Err); if ((i&7)==7) printf("\n"); } printf("\n== Mean errors ==\n"); for(i=0; i<64; i++) { double Err = Norm * (double)S->Errors[i]; printf(" %.3f", Err); if ((i&7)==7) printf("\n"); } printf("\n");}static const char *CHECK(double v, double l) { if (fabs(v)<=l) return "ok"; else return "FAIL!";}void report_stats(STATS_8x8 *S, const double *Limits){ int i; double Norm, PE, PMSE, OMSE, PME, OME; assert(S->Nb>0); Norm = 1. / (double)S->Nb; PE = 0.; for(i=0; i<64; i++) { if (PE<S->Max_Errors[i]) PE = S->Max_Errors[i]; } PMSE = 0.; OMSE = 0.; for(i=0; i<64; i++) { double Err = Norm * (double)S->Sqr_Errors[i]; OMSE += Err; if (PMSE < Err) PMSE = Err; } OMSE /= 64.; PME = 0.; OME = 0.; for(i=0; i<64; i++) { double Err = Norm * (double)S->Errors[i]; OME += Err; Err = fabs(Err); if (PME < Err) PME = Err; } OME /= 64.; printf( "Peak error: %4.4f\n", PE ); printf( "Peak MSE: %4.4f\n", PMSE ); printf( "Overall MSE: %4.4f\n", OMSE ); printf( "Peak ME: %4.4f\n", PME ); printf( "Overall ME: %4.4f\n", OME ); if (Limits!=0) { printf( "[PE<=%.4f %s] ", Limits[0], CHECK(PE, Limits[0]) ); printf( "\n" ); printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) ); printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) ); printf( "\n" ); printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) ); printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) ); printf( "\n" ); }}/*//////////////////////////////////////////////////////// *//* Pseudo-random generator specified by IEEE 1180 */static long ieee_seed = 1;static void ieee_reseed(long s) { ieee_seed = s;}static long ieee_rand(int Min, int Max){ static double z = (double) 0x7fffffff; long i,j; double x; ieee_seed = (ieee_seed * 1103515245) + 12345; i = ieee_seed & 0x7ffffffe; x = ((double) i) / z; x *= (Max-Min+1); j = (long)x; j = j + Min; assert(j>=Min && j<=Max); return (short)j;}#define CLAMP(x, M) (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))static double Cos[8][8];static void init_ref_dct(){ int i, j; for(i=0; i<8; i++) { double scale = (i == 0) ? sqrt(0.125) : 0.5; for (j=0; j<8; j++) Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) ); }}void ref_idct(short *M){ int i, j, k; double Tmp[8][8]; for(i=0; i<8; i++) { for(j=0; j<8; j++) { double Sum = 0.0; for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k]; Tmp[i][j] = Sum; } } for(i=0; i<8; i++) { for(j=0; j<8; j++) { double Sum = 0.0; for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j]; M[8*i+j] = (short)floor(Sum + .5); } }}void ref_fdct(short *M){ int i, j, k; double Tmp[8][8]; for(i=0; i<8; i++) { for(j=0; j<8; j++) { double Sum = 0.0; for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k]; Tmp[i][j] = Sum; } } for(i=0; i<8; i++) { for(j=0; j<8; j++) { double Sum = 0.0; for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j]; M[8*i+j] = (short)floor(Sum + 0.5); } }}void test_IEEE1180_compliance(int Min, int Max, int Sign){ static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 }; int Loops = 10000; int i, m, n; short Blk0[64]; /* reference */ short Blk[64], iBlk[64]; short Ref_FDCT[64]; short Ref_IDCT[64]; STATS_8x8 FStats; /* forward dct stats */ STATS_8x8 IStats; /* inverse dct stats */ CPU *cpu; init_ref_dct(); for(cpu = cpu_list; cpu->name!=0; ++cpu) { if (!init_cpu(cpu)) continue; printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n", cpu->name, Min, Max, Sign, Loops); init_stats(&IStats); init_stats(&FStats); ieee_reseed(1); for(n=0; n<Loops; ++n) { for(i=0; i<64; ++i) Blk0[i] = (short)ieee_rand(Min,Max) * Sign; /* hmm, I'm not quite sure this is exactly */ /* the tests described in the norm. check... */ memcpy(Ref_FDCT, Blk0, 64*sizeof(short)); ref_fdct(Ref_FDCT); for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 ); memcpy(Blk, Blk0, 64*sizeof(short)); emms(); fdct(Blk); emms(); for(i=0; i<64; i++) CLAMP( Blk[i], 2048 ); store_stats(&FStats, Blk, Ref_FDCT); memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short)); ref_idct(Ref_IDCT); for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 ); memcpy(iBlk, Ref_FDCT, 64*sizeof(short)); emms(); idct(iBlk); emms(); for(i=0; i<64; i++) CLAMP( iBlk[i], 256 ); store_stats(&IStats, iBlk, Ref_IDCT); } printf( "\n -- FDCT report --\n" );/* print_stats(&FStats); */ report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */ for(i=0; i<64; i++) Blk[i] = 0; emms(); fdct(Blk); emms(); for(m=i=0; i<64; i++) if (Blk[i]!=0) m++; printf( "FDCT(0) == 0 ? %s\n", (m!=0) ? "NOPE!" : "yup." ); printf( "\n -- IDCT report --\n" );/* print_stats(&IStats); */ report_stats(&IStats, ILimits); for(i=0; i<64; i++) Blk[i] = 0; emms(); idct(Blk); emms(); for(m=i=0; i<64; i++) if (Blk[i]!=0) m++; printf( "IDCT(0) == 0 ? %s\n", (m!=0) ? "NOPE!" : "yup." ); }}void test_dct_saturation(int Min, int Max){ /* test behaviour on input range fringe */ int i, n, p; CPU *cpu;/* const short IDCT_MAX = 2047; // 12bits input *//* const short IDCT_MIN = -2048; *//* const short IDCT_OUT = 256; // 9bits ouput */ const int Partitions = 4; const int Loops = 10000 / Partitions; init_ref_dct(); for(cpu = cpu_list; cpu->name!=0; ++cpu) { short Blk0[64], Blk[64]; STATS_8x8 Stats; if (!init_cpu(cpu)) continue; printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n", cpu->name, Min, Max ); /* FDCT tests // */ init_stats(&Stats); /* test each computation channels separately */ for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0; ref_fdct(Blk0); emms(); fdct(Blk); emms(); store_stats(&Stats, Blk, Blk0); for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0; ref_fdct(Blk0); emms(); fdct(Blk); emms(); store_stats(&Stats, Blk, Blk0); /* randomly saturated inputs */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -