Advertisement
Guest User

Untitled

a guest
May 26th, 2015
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.15 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <process.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <stdbool.h>
  6. #include <string.h>
  7. #include <intrin.h>
  8. #include <time.h>
  9.  
  10. // macros
  11. #define DEBUGP(x) if(1) { puts(x); system("pause"); }
  12. #define DEBUGF(x, ...) if(1) { printf(x, __VA_ARGS__); system("pause"); }
  13.  
  14. // typedefs
  15. typedef unsigned long long ulong;
  16. typedef unsigned int uint;
  17. typedef unsigned short int ushort;
  18. typedef unsigned char uchar;
  19.  
  20. // defs
  21. void set_icon();
  22. void thread_benchmark(void *);
  23. int _m128i_equals_uword(__m128i *, __m128i *);
  24. int _m128i_equals_sword(__m128i *, __m128i *);
  25. int _m128i_equals_sbyte(__m128i *, __m128i *);
  26. int _m128i_equals_ubyte(__m128i *, __m128i *);
  27. __declspec(noinline) float benchmark(const uint, const uint, char *, char *, int(*)(__m128i *, __m128i *));
  28.  
  29. // constants
  30. const float TICK_MODIFIER = 1000;
  31. const uint BENCHMARK_ROUNDS = 0x3FFFFFF;
  32. const uint BENCHMARK_OUTER_ROUNDS = 32;
  33. const char *const descriptions[] =
  34. {
  35.     "_SIDD_SWORD_OPS",
  36.     "_SIDD_UWORD_OPS",
  37.     "_SIDD_SBYTE_OPS",
  38.     "_SIDD_UBYTE_OPS"
  39. };
  40. int(*const methods[])(__m128i *, __m128i *) =
  41.  {
  42.      _m128i_equals_sword,
  43.      _m128i_equals_uword,
  44.      _m128i_equals_sbyte,
  45.      _m128i_equals_ubyte
  46.  };
  47.  
  48. // structs
  49. struct Stats
  50. {
  51.     uint threads;
  52.     uint totalRounds;
  53.     uint currentRound[4];
  54.     float averages[4];
  55.     uchar complete[4];
  56. } _stats;
  57.  
  58. struct ThreadInstructions
  59. {
  60.     const uint ordinal;
  61.     const uint innerRounds;
  62.     const uint outerRounds;
  63.     const char *textOne;
  64.     const char *textTwo;
  65.     int(*const method)(__m128i *, __m128i *);
  66. };
  67.  
  68. bool draw_stats(HANDLE consoleHandle, struct Stats *stats)
  69. {
  70.     const static CONSOLE_CURSOR_INFO hideCursorInfo = { .dwSize = 100, .bVisible = FALSE };
  71.     const static CONSOLE_CURSOR_INFO defaultCursorInfo = { .dwSize = 25, .bVisible = TRUE };
  72.     const static COORD zeroCoords = { .X = 0, .Y = 0 };
  73.  
  74.     SetConsoleCursorInfo(consoleHandle, &hideCursorInfo);
  75.     SetConsoleCursorPosition(consoleHandle, zeroCoords);
  76.  
  77.     puts(" STATISTICS\n"
  78.          "------------");
  79.     for (uint i = 0; i < 4; ++i)
  80.     {
  81.         printf("Thread %-2u\n", i+1);
  82.         printf("  Method:  %s                        \n", descriptions[i]);
  83.         printf("  Average: %-6g                        \n", _stats.averages[i]);
  84.         printf("  Round:   %u/%u                     \n", _stats.currentRound[i], BENCHMARK_OUTER_ROUNDS);
  85.         printf("  Done:    %u    \n\n", _stats.complete[i]);
  86.     }
  87.     SetConsoleCursorInfo(consoleHandle, &defaultCursorInfo);
  88.     return _stats.complete[0] &&
  89.            _stats.complete[1] &&
  90.            _stats.complete[2] &&
  91.            _stats.complete[3];
  92. }
  93.  
  94. int main()
  95. {
  96.     char *const first = _aligned_malloc(32, 16);
  97.     memcpy(first, "11113333333333334444333333333333", 32);
  98.     char *const second = _aligned_malloc(32, 16);
  99.     memcpy(second, "11113333333333334444333333333333", 32);
  100.  
  101.     HANDLE conHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  102.     draw_stats(conHandle, &_stats);
  103.  
  104.     struct ThreadInstructions *instructionPool = malloc(sizeof(struct ThreadInstructions) * 4);
  105.     for (uint i = 0; i < 4; ++i)
  106.     {
  107.         struct ThreadInstructions instructions =
  108.         {
  109.             .ordinal = i,
  110.             .innerRounds = BENCHMARK_ROUNDS,
  111.             .outerRounds = BENCHMARK_OUTER_ROUNDS,
  112.             .textOne = first,
  113.             .textTwo = second,
  114.             .method = methods[i],
  115.         };
  116.         memcpy(instructionPool + i, &instructions, sizeof(struct ThreadInstructions));
  117.         _beginthread(thread_benchmark, 0, (void *)(instructionPool + i));
  118.     }
  119.  
  120.     while (1)
  121.     {
  122.         if (draw_stats(conHandle, &_stats))
  123.         {
  124.             puts("\nFinished.");
  125.             break;
  126.         }
  127.         Sleep(100);
  128.     }
  129.  
  130.     free(instructionPool);
  131.     _aligned_free(first);
  132.     _aligned_free(second);
  133.  
  134.     system("pause");
  135.     return EXIT_SUCCESS;
  136. }
  137.  
  138. void __cdecl thread_benchmark(void *instructions)
  139. {
  140.     struct ThreadInstructions *instr = (struct ThreadInstructions *)instructions;
  141.     ulong total = 0;
  142.     uint count = 0;
  143.  
  144.     _stats.currentRound[instr->ordinal] = 0;
  145.     _stats.complete[instr->ordinal] = false;
  146.     _stats.averages[instr->ordinal] = 0;
  147.  
  148.     for (uint i = 0; i < instr->outerRounds; ++i)
  149.     {
  150.         clock_t begin = clock();
  151.         for (uint j = 0; j < instr->innerRounds; ++j)
  152.         {
  153.             instr->method((__m128i *)instr->textOne, (__m128i *)instr->textTwo);
  154.         }
  155.         clock_t end = clock();
  156.  
  157.         total += (end - begin);
  158.         ++count;
  159.  
  160.         _stats.currentRound[instr->ordinal] = i+1;
  161.         _stats.averages[instr->ordinal] = total / (float)count;
  162.     }
  163.     _stats.complete[instr->ordinal] = true;
  164. }
  165.  
  166. int _m128i_equals_sword(__m128i *x, __m128i *z)
  167. {
  168.     while (*(char *)x && *(char *)z)
  169.     {
  170.         if (_mm_cmpistri(*x, *z, _SIDD_CMP_EQUAL_EACH | _SIDD_SWORD_OPS))
  171.             return 0;
  172.         ++z;
  173.         x++;
  174.     }
  175.     return 1;
  176. }
  177.  
  178. int _m128i_equals_uword(__m128i *x, __m128i *z)
  179. {
  180.     while (*(char *)x && *(char *)z)
  181.     {
  182.         if (_mm_cmpistri(*x, *z, _SIDD_CMP_EQUAL_EACH | _SIDD_UWORD_OPS))
  183.             return 0;
  184.         ++z;
  185.         ++x;
  186.     }
  187.     return 1;
  188. }
  189.  
  190. int _m128i_equals_sbyte(__m128i *x, __m128i *z)
  191. {
  192.     while (*(char *)x && *(char *)z)
  193.     {
  194.         if (_mm_cmpistri(*x, *z, _SIDD_CMP_EQUAL_EACH | _SIDD_SBYTE_OPS))
  195.             return 0;
  196.         ++z;
  197.         ++x;
  198.     }
  199.     return 1;
  200. }
  201.  
  202. int _m128i_equals_ubyte(__m128i *x, __m128i *z)
  203. {
  204.     while (*(char *)x && *(char *)z)
  205.     {
  206.         if (_mm_cmpistri(*x, *z, _SIDD_CMP_EQUAL_EACH | _SIDD_UBYTE_OPS))
  207.             return 0;
  208.         z++;
  209.         x++;
  210.     }
  211.     return 1;
  212. }
  213. /*
  214. void set_icon()
  215. {
  216.     HICON icon = LoadImageA(NULL, "F:\\ok.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
  217.     HMODULE kernelModule = LoadLibraryA("kernel32.dll");
  218.     DWORD(__stdcall *setConsoleIcon)(HICON) = (DWORD(__stdcall *)(HICON))GetProcAddress(kernelModule, "SetConsoleIcon");
  219.     if (setConsoleIcon == NULL)
  220.     {
  221.         DWORD error = GetLastError();
  222.         printf("Couldn't set icon because of error %u.\n", error);
  223.         return;
  224.     }
  225.     setConsoleIcon(icon);
  226. }*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement