You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.2KB

  1. /*
  2. * MMX optimized DSP utils
  3. * Copyright (c) 2000, 2001 Gerard Lantau.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. *
  19. */
  20. #define TESTCPU_MAIN
  21. #include "dsputil.h"
  22. #include "../libavcodec/i386/cputest.c"
  23. #include "../libavcodec/i386/dsputil_mmx.c"
  24. #undef TESTCPU_MAIN
  25. #define PAD 0x10000
  26. /*
  27. * for testing speed of various routine - should be probably extended
  28. * for a general purpose regression test later
  29. *
  30. * currently only for i386 - FIXME
  31. */
  32. static const struct pix_func {
  33. char* name;
  34. op_pixels_func func;
  35. int mm_flags;
  36. } pix_func[] = {
  37. { "put_pixels_x2_mmx", put_pixels_y2_mmx, MM_MMX },
  38. { "put_pixels_x2_3dnow", put_pixels_y2_3dnow, MM_3DNOW },
  39. { "put_pixels_x2_mmx2", put_pixels_y2_mmx2, MM_MMXEXT | PAD },
  40. { "put_no_rnd_pixels_x2_mmx", put_no_rnd_pixels_x2_mmx, MM_MMX },
  41. { "put_no_rnd_pixels_x2_3dnow", put_no_rnd_pixels_x2_3dnow, MM_3DNOW },
  42. { "put_no_rnd_pixels_x2_mmx2", put_no_rnd_pixels_x2_mmx2, MM_MMXEXT | PAD },
  43. { "put_pixels_y2_mmx", put_pixels_y2_mmx, MM_MMX },
  44. { "put_pixels_y2_3dnow", put_pixels_y2_3dnow, MM_3DNOW },
  45. { "put_pixels_y2_mmx2", put_pixels_y2_mmx2, MM_MMXEXT | PAD },
  46. { 0, 0 }
  47. };
  48. static inline long long rdtsc()
  49. {
  50. long long l;
  51. asm volatile( "rdtsc\n\t"
  52. : "=A" (l)
  53. );
  54. return l;
  55. }
  56. static test_speed(int step)
  57. {
  58. const struct pix_func* pix = pix_func;
  59. const int linesize = 720;
  60. char empty[32768];
  61. char* bu =(char*)(((long)empty + 32) & ~0xf);
  62. while (pix->name)
  63. {
  64. int i;
  65. uint64_t te, ts;
  66. op_pixels_func func = pix->func;
  67. char* im = bu;
  68. if (!(pix->mm_flags & mm_flags))
  69. continue;
  70. printf("%30s... ", pix->name);
  71. fflush(stdout);
  72. ts = rdtsc();
  73. for(i=0; i<100000; i++){
  74. func(im, im + 1000, linesize, 16);
  75. im += step;
  76. if (im > bu + 20000)
  77. im = bu;
  78. }
  79. te = rdtsc();
  80. emms();
  81. printf("% 9d\n", (int)(te - ts));
  82. if (pix->mm_flags & PAD)
  83. puts("");
  84. pix++;
  85. }
  86. }
  87. int main(int argc, char* argv[])
  88. {
  89. int step = 16;
  90. if (argc > 1)
  91. {
  92. // something simple for now
  93. if (argc > 2 && (strcmp("-s", argv[1]) == 0
  94. || strcmp("-step", argv[1]) == 0))
  95. step = atoi(argv[2]);
  96. }
  97. mm_flags = mm_support();
  98. printf("dsptest: CPU flags:");
  99. if (mm_flags & MM_MMX)
  100. printf(" mmx");
  101. if (mm_flags & MM_MMXEXT)
  102. printf(" mmxext");
  103. if (mm_flags & MM_3DNOW)
  104. printf(" 3dnow");
  105. if (mm_flags & MM_SSE)
  106. printf(" sse");
  107. if (mm_flags & MM_SSE2)
  108. printf(" sse2");
  109. printf("\n");
  110. printf("Using step: %d\n", step);
  111. test_speed(step);
  112. }