diff options
author | David Schleef <ds@schleef.org> | 2006-01-31 03:19:35 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2006-01-31 03:19:35 +0000 |
commit | d14fb56ab84532957842d95dba6e41de2be1cc80 (patch) | |
tree | e5d26094d7aef0e0c5dcd5f5d6d8d0e7a7f89bad /testsuite/mmx_engine.c | |
parent | 056a04b9f623a60d01c50581a567501833e40221 (diff) | |
download | liboil-d14fb56ab84532957842d95dba6e41de2be1cc80.tar.gz |
* testsuite/mmx_engine.c: Add SSE2
Diffstat (limited to 'testsuite/mmx_engine.c')
-rw-r--r-- | testsuite/mmx_engine.c | 246 |
1 files changed, 225 insertions, 21 deletions
diff --git a/testsuite/mmx_engine.c b/testsuite/mmx_engine.c index fa7e7c4..a22217a 100644 --- a/testsuite/mmx_engine.c +++ b/testsuite/mmx_engine.c @@ -30,6 +30,7 @@ #endif #include <stdio.h> +#include <math.h> #include <liboil/liboil.h> #include <liboil/liboilprototype.h> @@ -37,7 +38,10 @@ #include <liboil/liboilcpu.h> #include <liboil/liboilrandom.h> +#define OFFSET 100 + void mmx_engine_test(void); +void sse2_engine_test(void); int main (int argc, char *argv[]) { @@ -46,26 +50,66 @@ int main (int argc, char *argv[]) oil_init (); cpu_flags = oil_cpu_get_flags (); - if (!(cpu_flags & OIL_IMPL_FLAG_MMX)) { - printf("No MMX.\n"); - exit(0); - } #ifdef HAVE_GCC_ASM #if defined(HAVE_I386) || defined(HAVE_AMD64) - mmx_engine_test(); + if (cpu_flags & OIL_IMPL_FLAG_MMX) { + mmx_engine_test(); + } else { + printf("No MMX.\n"); + } + if (cpu_flags & OIL_IMPL_FLAG_SSE2) { + sse2_engine_test(); + } else { + printf("No SSE2.\n"); + } #endif #endif return 0; } +int sci_sprint_alt(char *s,double x,double y) +{ + int errsig; + int maxsig; + int sigfigs; + double mantissa; + double error; + double mindigit; + + errsig = floor(log10(fabs(y))); + maxsig = floor(log10(fabs(x))); + mindigit = pow(10,errsig); + + if(maxsig<errsig)maxsig=errsig; + + sigfigs = maxsig-errsig+2; + + mantissa = x*pow(10,-maxsig); + error = y*pow(10,-errsig+1); + + if(isnan(x)){ + return sprintf(s,"%g",x); + } + if(errsig==1 && maxsig<4 && maxsig>1){ + return sprintf(s,"%0.0f(%2.0f)",x,error); + } + if(maxsig<=0 && maxsig>=-2){ + return sprintf(s,"%0.*f(%2.0f)",sigfigs-1-maxsig, + mantissa*pow(10,maxsig),error); + } + return sprintf(s,"%0.*f(%2.0f)e%d",sigfigs-1,mantissa,error,maxsig); +} + + #ifdef HAVE_GCC_ASM #if defined(HAVE_I386) || defined(HAVE_AMD64) void mmx_engine_test(void) { OilProfile prof; double ave, std; + char s[40]; int i; #define CHECK_LATENCY(insn) \ @@ -87,8 +131,9 @@ void mmx_engine_test(void) oil_profile_stop(&prof); \ } \ oil_profile_get_ave_std(&prof, &ave, &std); \ - ave -= 40; \ - printf("latency of " #insn ": %g +/- %g\n", ave/4000, std/4000); \ + ave -= OFFSET; \ + sci_sprint_alt(s,ave/4000,std/4000); \ + printf("latency of " #insn ": %s\n", s); CHECK_LATENCY(packssdw) CHECK_LATENCY(packsswb) @@ -145,21 +190,21 @@ void mmx_engine_test(void) ".align 16\n" \ "1:\n" \ " " #insn " %%mm0, %%mm1\n" \ - " " #insn " %%mm2, %%mm3\n" \ - " " #insn " %%mm4, %%mm5\n" \ - " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm2\n" \ + " " #insn " %%mm0, %%mm3\n" \ + " " #insn " %%mm0, %%mm4\n" \ " " #insn " %%mm0, %%mm1\n" \ - " " #insn " %%mm2, %%mm3\n" \ - " " #insn " %%mm4, %%mm5\n" \ - " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm2\n" \ + " " #insn " %%mm0, %%mm3\n" \ + " " #insn " %%mm0, %%mm4\n" \ " " #insn " %%mm0, %%mm1\n" \ - " " #insn " %%mm2, %%mm3\n" \ - " " #insn " %%mm4, %%mm5\n" \ - " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm2\n" \ + " " #insn " %%mm0, %%mm3\n" \ + " " #insn " %%mm0, %%mm4\n" \ " " #insn " %%mm0, %%mm1\n" \ - " " #insn " %%mm2, %%mm3\n" \ - " " #insn " %%mm4, %%mm5\n" \ - " " #insn " %%mm6, %%mm7\n" \ + " " #insn " %%mm0, %%mm2\n" \ + " " #insn " %%mm0, %%mm3\n" \ + " " #insn " %%mm0, %%mm4\n" \ " decl %%ecx\n" \ " jne 1b\n" \ " emms\n" \ @@ -167,8 +212,166 @@ void mmx_engine_test(void) oil_profile_stop(&prof); \ } \ oil_profile_get_ave_std(&prof, &ave, &std); \ - ave -= 40; \ - printf("throughput of " #insn ": %g +/- %g\n", ave/16000, std/16000); \ + ave -= OFFSET; \ + sci_sprint_alt(s,ave/16000,std/16000); \ + printf("throughput of " #insn ": %s\n", s); + + CHECK_THROUGHPUT(packssdw) + CHECK_THROUGHPUT(packsswb) + CHECK_THROUGHPUT(packuswb) + CHECK_THROUGHPUT(paddb) + CHECK_THROUGHPUT(paddd) + CHECK_THROUGHPUT(paddsb) + CHECK_THROUGHPUT(paddsw) + CHECK_THROUGHPUT(paddusb) + CHECK_THROUGHPUT(paddusw) + CHECK_THROUGHPUT(paddw) + CHECK_THROUGHPUT(pand) + CHECK_THROUGHPUT(pandn) + CHECK_THROUGHPUT(pcmpeqb) + CHECK_THROUGHPUT(pcmpeqd) + CHECK_THROUGHPUT(pcmpeqw) + CHECK_THROUGHPUT(pcmpgtb) + CHECK_THROUGHPUT(pcmpgtd) + CHECK_THROUGHPUT(pcmpgtw) + CHECK_THROUGHPUT(pmaddwd) + CHECK_THROUGHPUT(pmulhw) + CHECK_THROUGHPUT(pmullw) + CHECK_THROUGHPUT(pmulhuw) + CHECK_THROUGHPUT(por) + CHECK_THROUGHPUT(pslld) + CHECK_THROUGHPUT(psllq) + CHECK_THROUGHPUT(psllw) + CHECK_THROUGHPUT(psrad) + CHECK_THROUGHPUT(psraw) + CHECK_THROUGHPUT(psrld) + CHECK_THROUGHPUT(psrlq) + CHECK_THROUGHPUT(psrlw) + CHECK_THROUGHPUT(psubb) + CHECK_THROUGHPUT(psubd) + CHECK_THROUGHPUT(psubsb) + CHECK_THROUGHPUT(psubsw) + CHECK_THROUGHPUT(psubusb) + CHECK_THROUGHPUT(psubusw) + CHECK_THROUGHPUT(psubw) + CHECK_THROUGHPUT(punpckhbw) + CHECK_THROUGHPUT(punpckhdq) + CHECK_THROUGHPUT(punpckhwd) + CHECK_THROUGHPUT(punpcklbw) + CHECK_THROUGHPUT(punpckldq) + CHECK_THROUGHPUT(punpcklwd) + CHECK_THROUGHPUT(pxor) + +#undef CHECK_LATENCY +#undef CHECK_THROUGHPUT +} + +void sse2_engine_test(void) +{ + OilProfile prof; + double ave, std; + char s[40]; + int i; + +#define CHECK_LATENCY(insn) \ + oil_profile_init (&prof); \ + for(i=0;i<10;i++) { \ + oil_profile_start(&prof); \ + asm volatile ( \ + " mov $1000, %%ecx\n" \ + ".align 16\n" \ + "1:\n" \ + " " #insn " %%xmm0, %%xmm1\n" \ + " " #insn " %%xmm1, %%xmm2\n" \ + " " #insn " %%xmm2, %%xmm3\n" \ + " " #insn " %%xmm3, %%xmm0\n" \ + " decl %%ecx\n" \ + " jne 1b\n" \ + :::"ecx"); \ + oil_profile_stop(&prof); \ + } \ + oil_profile_get_ave_std(&prof, &ave, &std); \ + ave -= OFFSET; \ + sci_sprint_alt(s,ave/4000,std/4000); \ + printf("latency of " #insn ": %s\n", s); + + CHECK_LATENCY(packssdw) + CHECK_LATENCY(packsswb) + CHECK_LATENCY(packuswb) + CHECK_LATENCY(paddb) + CHECK_LATENCY(paddd) + CHECK_LATENCY(paddsb) + CHECK_LATENCY(paddsw) + CHECK_LATENCY(paddusb) + CHECK_LATENCY(paddusw) + CHECK_LATENCY(paddw) + CHECK_LATENCY(pand) + CHECK_LATENCY(pandn) + CHECK_LATENCY(pcmpeqb) + CHECK_LATENCY(pcmpeqd) + CHECK_LATENCY(pcmpeqw) + CHECK_LATENCY(pcmpgtb) + CHECK_LATENCY(pcmpgtd) + CHECK_LATENCY(pcmpgtw) + CHECK_LATENCY(pmaddwd) + CHECK_LATENCY(pmulhw) + CHECK_LATENCY(pmullw) + CHECK_LATENCY(pmulhuw) + CHECK_LATENCY(por) + CHECK_LATENCY(pslld) + CHECK_LATENCY(psllq) + CHECK_LATENCY(psllw) + CHECK_LATENCY(psrad) + CHECK_LATENCY(psraw) + CHECK_LATENCY(psrld) + CHECK_LATENCY(psrlq) + CHECK_LATENCY(psrlw) + CHECK_LATENCY(psubb) + CHECK_LATENCY(psubd) + CHECK_LATENCY(psubsb) + CHECK_LATENCY(psubsw) + CHECK_LATENCY(psubusb) + CHECK_LATENCY(psubusw) + CHECK_LATENCY(psubw) + CHECK_LATENCY(punpckhbw) + CHECK_LATENCY(punpckhdq) + CHECK_LATENCY(punpckhwd) + CHECK_LATENCY(punpcklbw) + CHECK_LATENCY(punpckldq) + CHECK_LATENCY(punpcklwd) + CHECK_LATENCY(pxor) + +#define CHECK_THROUGHPUT(insn) \ + oil_profile_init (&prof); \ + for(i=0;i<10;i++) { \ + oil_profile_start(&prof); \ + asm volatile ( \ + " mov $1000, %%ecx\n" \ + ".align 16\n" \ + "1:\n" \ + " " #insn " %%xmm0, %%xmm1\n" \ + " " #insn " %%xmm0, %%xmm2\n" \ + " " #insn " %%xmm0, %%xmm3\n" \ + " " #insn " %%xmm0, %%xmm4\n" \ + " " #insn " %%xmm0, %%xmm5\n" \ + " " #insn " %%xmm0, %%xmm6\n" \ + " " #insn " %%xmm0, %%xmm7\n" \ + " " #insn " %%xmm0, %%xmm1\n" \ + " " #insn " %%xmm0, %%xmm2\n" \ + " " #insn " %%xmm0, %%xmm3\n" \ + " " #insn " %%xmm0, %%xmm4\n" \ + " " #insn " %%xmm0, %%xmm5\n" \ + " " #insn " %%xmm0, %%xmm6\n" \ + " " #insn " %%xmm0, %%xmm7\n" \ + " decl %%ecx\n" \ + " jne 1b\n" \ + :::"ecx"); \ + oil_profile_stop(&prof); \ + } \ + oil_profile_get_ave_std(&prof, &ave, &std); \ + ave -= OFFSET; \ + sci_sprint_alt(s,ave/14000,std/14000); \ + printf("throughput of " #insn ": %s\n", s); CHECK_THROUGHPUT(packssdw) CHECK_THROUGHPUT(packsswb) @@ -219,3 +422,4 @@ void mmx_engine_test(void) #endif #endif + |