* somewhat more advanced test suit for dsp code - for now i386 only
authorZdenek Kabelac <kabi@informatics.muni.cz>
Thu, 23 May 2002 13:34:22 +0000 (13:34 +0000)
committerZdenek Kabelac <kabi@informatics.muni.cz>
Thu, 23 May 2002 13:34:22 +0000 (13:34 +0000)
  cd test ; make dsptest ; ./dsptest

Originally committed as revision 568 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/i386/dsputil_mmx.c
tests/Makefile
tests/dsptest.c [new file with mode: 0644]

index 483e19a..7bcb1e5 100644 (file)
@@ -1082,45 +1082,4 @@ void dsputil_set_bit_exact_mmx(void)
     }
 }
 
-#else // TESTCPU_MAIN
-/*
- * for testing speed of various routine - should be probably extended
- * for a general purpose regression test later
- *
- * for now use it this way:
- *
- * gcc -O4 -fomit-frame-pointer -DHAVE_AV_CONFIG_H -DTESTCPU_MAIN  -I../.. -o test dsputil_mmx.c
- *
- * in libavcodec/i386 directory - then run ./test
- */
-static inline long long rdtsc()
-{
-    long long l;
-    asm volatile(   "rdtsc\n\t"
-                   : "=A" (l)
-               );
-    return l;
-}
-
-int main(int argc, char* argv[])
-{
-    volatile int v;
-    int i;
-    const int linesize = 720;
-    char empty[32768];
-    uint64_t te, ts = rdtsc();
-    char* im, *bu = empty;
-    op_pixels_func fc = put_pixels_y2_mmx2;
-    bu += 32;
-    bu =(char*)(((long)bu) & ~0xf); // 16 bytes alignment
-    im = bu;
-    for(i=0; i<1000000; i++){
-       fc(im, im + 1000, linesize, 16);
-       im += 4; //
-       if (im > bu + 10000)
-            im = bu;
-    }
-    te = rdtsc();
-    printf("CPU Ticks: %7d\n", (int)(te - ts));
-}
 #endif
index e661a46..cb3b387 100644 (file)
@@ -36,6 +36,12 @@ asynth1.sw: audiogen
 audiogen: audiogen.c
        $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $<
 
+DSPDEPS = $(SRC_PATH)/libavcodec/i386/dsputil_mmx.c \
+ $(SRC_PATH)/libavcodec/i386/dsputil_mmx_avg.h 
+
+dsptest: dsptest.c $(DSPDEPS)
+       $(CC) -O4 -fomit-frame-pointer -DHAVE_AV_CONFIG_H -I.. -I$(SRC_PATH)/libavcodec/i386 -I$(SRC_PATH)/libavcodec/ -o $@ $<
+
 clean:
        rm -rf vsynth1
        rm -f asynth1.sw *~ audiogen videogen
diff --git a/tests/dsptest.c b/tests/dsptest.c
new file mode 100644 (file)
index 0000000..57596dd
--- /dev/null
@@ -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);
+}