summaryrefslogtreecommitdiff
path: root/tests/dsptest.c
diff options
context:
space:
mode:
authorZdenek Kabelac <kabi@informatics.muni.cz>2002-05-23 13:34:22 +0000
committerZdenek Kabelac <kabi@informatics.muni.cz>2002-05-23 13:34:22 +0000
commitec9a41f57d3df89859a5eb9addd3f0de167909ba (patch)
tree6ab19c1f8ad638821d264a279742df7039e572c1 /tests/dsptest.c
parent6efad6fd85b2326142939b57f8720341031f656c (diff)
* somewhat more advanced test suit for dsp code - for now i386 only
cd test ; make dsptest ; ./dsptest Originally committed as revision 568 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'tests/dsptest.c')
-rw-r--r--tests/dsptest.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/tests/dsptest.c b/tests/dsptest.c
new file mode 100644
index 0000000000..57596dd1f0
--- /dev/null
+++ b/tests/dsptest.c
@@ -0,0 +1,125 @@
+/*
+ * MMX optimized DSP utils
+ * Copyright (c) 2000, 2001 Gerard Lantau.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define TESTCPU_MAIN
+#include "dsputil.h"
+#include "../libavcodec/i386/cputest.c"
+#include "../libavcodec/i386/dsputil_mmx.c"
+#undef TESTCPU_MAIN
+
+#define PAD 0x10000
+/*
+ * for testing speed of various routine - should be probably extended
+ * for a general purpose regression test later
+ *
+ * currently only for i386 - FIXME
+ */
+static const struct pix_func {
+ char* name;
+ op_pixels_func func;
+ int mm_flags;
+} pix_func[] = {
+ { "put_pixels_x2_mmx", put_pixels_y2_mmx, MM_MMX },
+ { "put_pixels_x2_3dnow", put_pixels_y2_3dnow, MM_3DNOW },
+ { "put_pixels_x2_mmx2", put_pixels_y2_mmx2, MM_MMXEXT | PAD },
+
+ { "put_no_rnd_pixels_x2_mmx", put_no_rnd_pixels_x2_mmx, MM_MMX },
+ { "put_no_rnd_pixels_x2_3dnow", put_no_rnd_pixels_x2_3dnow, MM_3DNOW },
+ { "put_no_rnd_pixels_x2_mmx2", put_no_rnd_pixels_x2_mmx2, MM_MMXEXT | PAD },
+
+ { "put_pixels_y2_mmx", put_pixels_y2_mmx, MM_MMX },
+ { "put_pixels_y2_3dnow", put_pixels_y2_3dnow, MM_3DNOW },
+ { "put_pixels_y2_mmx2", put_pixels_y2_mmx2, MM_MMXEXT | PAD },
+ { 0, 0 }
+};
+
+static inline long long rdtsc()
+{
+ long long l;
+ asm volatile( "rdtsc\n\t"
+ : "=A" (l)
+ );
+ return l;
+}
+
+static test_speed(int step)
+{
+ const struct pix_func* pix = pix_func;
+ const int linesize = 720;
+ char empty[32768];
+ char* bu =(char*)(((long)empty + 32) & ~0xf);
+
+ while (pix->name)
+ {
+ int i;
+ uint64_t te, ts;
+ op_pixels_func func = pix->func;
+ char* im = bu;
+
+ if (!(pix->mm_flags & mm_flags))
+ continue;
+
+ printf("%30s... ", pix->name);
+ fflush(stdout);
+ ts = rdtsc();
+ for(i=0; i<100000; i++){
+ func(im, im + 1000, linesize, 16);
+ im += step;
+ if (im > bu + 20000)
+ im = bu;
+ }
+ te = rdtsc();
+ emms();
+ printf("% 9d\n", (int)(te - ts));
+ if (pix->mm_flags & PAD)
+ puts("");
+ pix++;
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ int step = 16;
+
+ if (argc > 1)
+ {
+ // something simple for now
+ if (argc > 2 && (strcmp("-s", argv[1]) == 0
+ || strcmp("-step", argv[1]) == 0))
+ step = atoi(argv[2]);
+ }
+
+ mm_flags = mm_support();
+ printf("dsptest: CPU flags:");
+ if (mm_flags & MM_MMX)
+ printf(" mmx");
+ if (mm_flags & MM_MMXEXT)
+ printf(" mmxext");
+ if (mm_flags & MM_3DNOW)
+ printf(" 3dnow");
+ if (mm_flags & MM_SSE)
+ printf(" sse");
+ if (mm_flags & MM_SSE2)
+ printf(" sse2");
+ printf("\n");
+
+ printf("Using step: %d\n", step);
+ test_speed(step);
+}