Advertisement
MonoS

test code for BM3D

Jan 2nd, 2016
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <random>
  3. #include <tmmintrin.h>
  4. #include <x86intrin.h>
  5. #include "iacaMarks.h"
  6.  
  7. using namespace std;
  8.  
  9. int const ITER  = 100000000;
  10. int const ITER2 = 10000000;
  11.  
  12. #define AVX
  13. #define SSE
  14.  
  15.  
  16. #define TEST
  17. #define TEST_AVX
  18.  
  19. #ifdef SSE
  20. inline __m128 _mm_abs_ps(__m128 x)
  21. {
  22.     static __m128 const Mask = _mm_castsi128_ps(_mm_set1_epi32(~0x80000000));
  23.  
  24.     __m128 abs = _mm_and_ps(Mask, x);
  25.  
  26.     return abs;
  27. }
  28. #endif // SSE
  29.  
  30. #ifdef AVX
  31. inline __m256 _mm256_abs_ps(__m256 x)
  32. {
  33.     static __m256 const Mask = _mm256_castsi256_ps(_mm256_set1_epi32(~0x80000000));
  34.  
  35.     __m256 abs = _mm256_and_ps(Mask, x);
  36.  
  37.     return abs;
  38. }
  39. #endif // AVX
  40.  
  41. union FI{
  42. float f;
  43. uint32_t i;
  44. };
  45.  
  46. inline float ffabs(float a)
  47. {
  48.     /*
  49.     FI fi;
  50.     fi.f = a;
  51.     fi.i &= (~0x80000000);
  52.  
  53.     return fi.f;
  54.     */
  55.     uint32_t i = *(int*)&a & (~0x80000000);
  56.  
  57.     return *(float*)&i;
  58. }
  59.  
  60. #ifndef TEST
  61. #undef IACA_END
  62. #define IACA_END
  63.  
  64. #undef IACA_START
  65. #define IACA_START
  66. #endif // TEST
  67.  
  68. #define IACA_SART_AVX IACA_START
  69. #define IACA_END_AVX IACA_END
  70.  
  71. #define IACA_SART_SSE IACA_START
  72. #define IACA_END_SSE IACA_END
  73.  
  74. int main()
  75. {
  76.     /*
  77.     mt19937 randGen(42);
  78.     float *srcp = new float[ITER];
  79.     float *thrp = new float[ITER];
  80.     uniform_real_distribution<float> distribution(-123453,123453);
  81.  
  82.     for(int j = 0; j < 20; j++)
  83.     {
  84.         int retainedCoefs = 0;
  85.         int retainedCoefsAbs = 0;
  86.         cout<<"batch: "<<j<<endl;
  87.         for (int i = 0; i < ITER; i++)
  88.         {
  89.             srcp[i] = distribution(randGen);
  90.             thrp[i] = distribution(randGen);
  91.         }
  92.  
  93.         for (int i = 0; i < ITER; i++)
  94.         {
  95.             if (srcp[i] > thrp[i] || srcp[i] < -thrp[i])
  96.             {
  97.                 ++retainedCoefs;
  98.             }
  99.         }
  100.  
  101.         for (int i = 0; i < ITER; i++)
  102.         {
  103.             if (fabs(srcp[i]) > thrp[i])
  104.             {
  105.                 ++retainedCoefsAbs;
  106.             }
  107.         }
  108.  
  109.         cout<<retainedCoefs<<endl<<retainedCoefsAbs<<endl;
  110.  
  111.         if(retainedCoefs != retainedCoefsAbs)
  112.         {
  113.             system("pause");
  114.         }
  115.  
  116.     }
  117.  
  118. */
  119. /*
  120.     __m128i cmp_sum = _mm_set_epi32(1,2,3,4);
  121.     int retainedCoefs = 0;
  122.     volatile int iter = 10000000;
  123.     uint64_t start = __rdtsc();
  124.     for(int i = 0; i < iter; ++i)
  125.     {
  126.         alignas(16) int32_t cmp_sum_i32[4];
  127.         _mm_store_si128(reinterpret_cast<__m128i *>(cmp_sum_i32), cmp_sum);
  128.         retainedCoefs += cmp_sum_i32[0] + cmp_sum_i32[1] + cmp_sum_i32[2] + cmp_sum_i32[3];
  129.     }
  130.     uint64_t end = __rdtsc();
  131.  
  132.     cout<<retainedCoefs<<endl;
  133.     cout<<end-start<<endl;
  134.  
  135.     retainedCoefs = 0;
  136.  
  137.     start = __rdtsc();
  138.     for(int i = 0; i < iter; ++i)
  139.     {
  140.         __m128i cmp_sum_t = _mm_hadd_epi32(cmp_sum, cmp_sum);
  141.         cmp_sum_t = _mm_hadd_epi32(cmp_sum_t, cmp_sum_t);
  142.         retainedCoefs += _mm_extract_epi32(cmp_sum_t, 0);
  143.     }
  144.     end = __rdtsc();
  145.  
  146.     cout<<retainedCoefs<<endl;
  147.     cout<<end-start<<endl;
  148. */
  149. /*
  150.     mt19937 randGen(42);
  151.     float refp;
  152.     uniform_real_distribution<float> distribution(0,1);
  153.  
  154.  
  155.  
  156.     for(int j = 0; j < 20; j++)
  157.     {
  158.         float wienerCoef = 0;
  159.         float wienerCoef_opt = 0;
  160.         const float sigmaSquare = distribution(randGen);
  161.         const float rcp_sigmaSquare = 1/sigmaSquare;
  162.  
  163.         cout<<"batch: "<<j<<endl;
  164.         //for (int i = 0; i < ITER; i++)
  165.         {
  166.             //srcp[i] = distribution(randGen);
  167.             refp = distribution(randGen);
  168.         }
  169.  
  170.         //for (int i = 0; i < ITER; i++)
  171.         {
  172.             const float refSquare = refp * refp;
  173.             wienerCoef = refSquare / (refSquare + sigmaSquare);
  174.         }
  175.  
  176.         //for (int i = 0; i < ITER; i++)
  177.         {
  178.             const float refSquare = refp * refp;
  179.             wienerCoef_opt = 1/(1 + (refSquare * rcp_sigmaSquare));
  180.         }
  181.  
  182.         cout<<wienerCoef<<endl<<wienerCoef_opt<<endl;
  183.  
  184.     }
  185. */
  186.  
  187.     mt19937 randGen(42);
  188.     //float *srcp = new float[ITER];
  189.     float *srcpC= new float[ITER];
  190.     float *srcpS= new float[ITER];
  191.     float *srcpA= new float[ITER];
  192.     float *thrp = new float[ITER];
  193.  
  194.     int retainedCoefsC = 0, retainedCoefsS = 0, retainedCoefsA = 0;
  195.  
  196.     uint64_t CC, CS, CA;
  197.     uint64_t start, end;
  198.  
  199.     uniform_real_distribution<float> distribution(-1.0f, 1.0f);
  200.  
  201.     for(int j = 0; j < 20; j++)
  202.     {
  203.         cout<<"batch: "<<j<<endl;
  204.  
  205.         CC = 0; CS = 0; CA = 0;
  206.         for (int i = 0; i < ITER; i++)
  207.         {
  208.             srcpC[i] = distribution(randGen);
  209.             srcpS[i] = srcpC[i];
  210.             srcpA[i] = srcpC[i];
  211.             thrp[i] = distribution(randGen);
  212.         }
  213.  
  214. #ifdef SSE
  215.     start = __rdtsc();
  216.     //IACA_SART_SSE;
  217.     //SSE2
  218.     {
  219.         static const ptrdiff_t simd_step = 4;
  220.         __m128i cmp_sum = _mm_setzero_si128();
  221.         __m128 zero = _mm_setzero_ps();
  222.         for (int i = 0; i < ITER; i += simd_step)
  223.         {
  224.  
  225.             const __m128 s1 = _mm_load_ps(&srcpS[i]);
  226.             const __m128 t1p = _mm_load_ps(&thrp[i]);
  227.  
  228.             const __m128 abs = _mm_abs_ps(s1);
  229.             const __m128 cmp = _mm_cmpgt_ps(abs, t1p);
  230.  
  231.  
  232.             const __m128 d1 = _mm_and_ps(cmp, s1);
  233.             _mm_store_ps(&srcpS[i], d1);
  234.  
  235.             cmp_sum = _mm_sub_epi32(cmp_sum, _mm_castps_si128(cmp));
  236.         }
  237.  
  238.         alignas(16) int32_t cmp_sum_i32[4];
  239.         _mm_store_si128(reinterpret_cast<__m128i *>(cmp_sum_i32), cmp_sum);
  240.         retainedCoefsS += cmp_sum_i32[0] + cmp_sum_i32[1] + cmp_sum_i32[2] + cmp_sum_i32[3];
  241.     }
  242.     //IACA_END_SSE;
  243.     end = __rdtsc();
  244.     CS = end - start;
  245.  
  246.     cout<<retainedCoefsS<<endl;
  247. #endif //SSE
  248.  
  249. #ifdef AVX
  250.     start = __rdtsc();
  251.  
  252.     //AVX
  253.     {
  254.         static const ptrdiff_t simd_step = 8;
  255.  
  256.         __m128i cmp_sum   = _mm_setzero_si128();
  257.         __m128i cmp_0, cmp_1;
  258.  
  259.         //__m256i cmp_sum256 = _mm256_setzero_si256();
  260.  
  261.         for (int i = 0; i < ITER; i += simd_step)
  262.         {
  263.             //IACA_SART_AVX;
  264.  
  265.             __m256 s1 = _mm256_load_ps(&srcpA[i]);
  266.             __m256 t1 = _mm256_load_ps(&thrp[i]);
  267.  
  268.             __m256 abs = _mm256_abs_ps(s1);
  269.             __m256 cmp = _mm256_cmp_ps(abs, t1, _CMP_GT_OQ);
  270.  
  271.             __m256 d1 = _mm256_and_ps(cmp, s1);
  272.             _mm256_storeu_ps(&srcpA[i], d1);
  273.  
  274.             //cmp_sum256 = _mm256_sub_epi32(cmp_sum256, _mm256_castps_si256(cmp));
  275.  
  276.             cmp_0 = _mm256_extractf128_si256(_mm256_castps_si256(cmp), 0);
  277.             cmp_1 = _mm256_extractf128_si256(_mm256_castps_si256(cmp), 1);
  278.  
  279.             _mm256_zeroupper();
  280.  
  281.             cmp_sum = _mm_sub_epi32(cmp_sum, cmp_0);
  282.             cmp_sum = _mm_sub_epi32(cmp_sum, cmp_1);
  283.         }
  284.         /*
  285.         alignas(32) int32_t cmp_sum_i32[8];
  286.         _mm256_store_si256(reinterpret_cast<__m256i *>(cmp_sum_i32), cmp_sum256);
  287.         retainedCoefsA += cmp_sum_i32[0] + cmp_sum_i32[1] + cmp_sum_i32[2] + cmp_sum_i32[3]+\
  288.                           cmp_sum_i32[4] + cmp_sum_i32[5] + cmp_sum_i32[6] + cmp_sum_i32[7];
  289.         */
  290.         //IACA_END_AVX;
  291.         alignas(16) int32_t cmp_sum_i32[4];
  292.         _mm_store_si128(reinterpret_cast<__m128i *>(cmp_sum_i32), cmp_sum);
  293.         retainedCoefsA += cmp_sum_i32[0] + cmp_sum_i32[1] + cmp_sum_i32[2] + cmp_sum_i32[3];
  294.  
  295.     }
  296.  
  297.     end = __rdtsc();
  298.     CA = end - start;
  299.  
  300.     cout<<retainedCoefsA<<endl;
  301. #endif
  302.     start = __rdtsc();
  303.     //C
  304.     {
  305.         for (int i = 0; i < ITER; ++i)
  306.         {
  307.             //if (srcpC[i] > thrp[i] || srcpC[i] < -thrp[i])
  308.             if(ffabs(srcpC[i]) > thrp[i])
  309.             {
  310.                 ++retainedCoefsC;
  311.             }
  312.             else
  313.             {
  314.                 srcpC[i] = 0;
  315.             }
  316.         }
  317.     }
  318.     end = __rdtsc();
  319.     CC = end - start;
  320.  
  321.     cout<<retainedCoefsC<<endl;
  322.     printf("Cicli C  : %f\n"
  323.            "Cicli SSE: %f\n"
  324.            "Cicli AVX: %f\n"
  325.            "Guadagno SSE/AVX: %f\n",
  326.            (float)CC/(float)ITER, CS/(float)ITER*4, CA/(float)ITER*8, (float)CS/(float)CA
  327.            );
  328.  
  329.     }
  330.     return 0;
  331. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement