fork download
  1. //#define VAR A
  2. #define SIMD
  3.  
  4. #include <cassert>
  5. #include <algorithm>
  6. #include <iterator>
  7. #include <random>
  8. #include <vector>
  9. #include <functional>
  10. #include <emmintrin.h>
  11. #include <tmmintrin.h>
  12. #include <xmmintrin.h>
  13. #include <cstdint>
  14.  
  15. int signumA(int x) {
  16. if (x > 0)
  17. return 1;
  18. if (x < 0)
  19. return -1;
  20. if (x == 0)
  21. return 0;
  22. assert(false);
  23. }
  24. int signumB(int x) {
  25. return (x>0) - (x<0);
  26. }
  27. int signumC(int x) {
  28. return std::min(std::max(-1, x), 1);
  29. }
  30. int signumD(int x) {
  31. int y = 0;
  32. if (x > 0) y = 1;
  33. if (x < 0) y = -1;
  34. return y;
  35. }
  36. int signumE(int x) {
  37. return x ? x/std::abs(x) : 0;
  38. }
  39.  
  40. void signum4(std::int32_t* result, const std::int32_t* values)
  41. {
  42. _mm_store_si128(
  43. reinterpret_cast<__m128i*>(result),
  44. _mm_sign_epi32(_mm_set1_epi32(1), _mm_load_si128(reinterpret_cast<const __m128i*>(values))));
  45. }
  46.  
  47. #define CONCAT2(a, b) a ## b
  48. #define CONCAT(a, b) CONCAT2(a, b)
  49. #define signumX CONCAT(signum, VAR)
  50.  
  51. int main(int argc, const char *argv[]) {
  52. int length = std::atoi(argv[1]);
  53. int iterations = std::atoi(argv[2]);
  54.  
  55. // make length the smallest multiple of 4 that is at least
  56. // the requested length.
  57. if (length % 4 > 0)
  58. length += 4 - length % 4;
  59.  
  60. std::mt19937 mersenne_engine(42); // fixed seed
  61. std::uniform_int_distribution<int> dist(-1000, 1000);
  62.  
  63. int* nums = static_cast<int*>(_mm_malloc(sizeof(int) * length, alignof(__m128i)));
  64. int* results = static_cast<int*>(_mm_malloc(sizeof(int) * length, alignof(__m128i)));
  65.  
  66. generate_n(nums, length, bind(dist, mersenne_engine));
  67.  
  68. while (iterations--) {
  69. #ifdef SIMD
  70. for (int i = 0; i < length; i += 4)
  71. signum4(results + i, nums + i);
  72. #else
  73. for (int i = 0; i < length; ++i)
  74. results[i] = signumX(nums[i]);
  75. #endif
  76. }
  77.  
  78. return 0;
  79. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp: In function 'void signum4(int32_t*, const int32_t*)':
prog.cpp:42:17: warning: SSE vector return without SSE enabled changes the ABI [-Wpsabi]
  _mm_store_si128(
                 ^
In file included from /usr/lib/gcc/i586-linux-gnu/5/include/xmmintrin.h:1249:0,
                 from /usr/lib/gcc/i586-linux-gnu/5/include/x86intrin.h:31,
                 from /usr/include/i386-linux-gnu/c++/5/bits/opt_random.h:33,
                 from /usr/include/c++/5/random:50,
                 from /usr/include/c++/5/bits/stl_algo.h:66,
                 from /usr/include/c++/5/algorithm:62,
                 from prog.cpp:5:
/usr/lib/gcc/i586-linux-gnu/5/include/emmintrin.h:708:1: error: inlining failed in call to always_inline 'void _mm_store_si128(__m128i*, __m128i)': target specific option mismatch
 _mm_store_si128 (__m128i *__P, __m128i __B)
 ^
prog.cpp:44:95: error: called from here
   _mm_sign_epi32(_mm_set1_epi32(1), _mm_load_si128(reinterpret_cast<const __m128i*>(values))));
                                                                                               ^
In file included from /usr/lib/gcc/i586-linux-gnu/5/include/x86intrin.h:37:0,
                 from /usr/include/i386-linux-gnu/c++/5/bits/opt_random.h:33,
                 from /usr/include/c++/5/random:50,
                 from /usr/include/c++/5/bits/stl_algo.h:66,
                 from /usr/include/c++/5/algorithm:62,
                 from prog.cpp:5:
/usr/lib/gcc/i586-linux-gnu/5/include/tmmintrin.h:160:1: error: inlining failed in call to always_inline '__m128i _mm_sign_epi32(__m128i, __m128i)': target specific option mismatch
 _mm_sign_epi32 (__m128i __X, __m128i __Y)
 ^
prog.cpp:42:17: error: called from here
  _mm_store_si128(
                 ^
In file included from /usr/lib/gcc/i586-linux-gnu/5/include/xmmintrin.h:1249:0,
                 from /usr/lib/gcc/i586-linux-gnu/5/include/x86intrin.h:31,
                 from /usr/include/i386-linux-gnu/c++/5/bits/opt_random.h:33,
                 from /usr/include/c++/5/random:50,
                 from /usr/include/c++/5/bits/stl_algo.h:66,
                 from /usr/include/c++/5/algorithm:62,
                 from prog.cpp:5:
/usr/lib/gcc/i586-linux-gnu/5/include/emmintrin.h:637:1: error: inlining failed in call to always_inline '__m128i _mm_set1_epi32(int)': target specific option mismatch
 _mm_set1_epi32 (int __A)
 ^
prog.cpp:42:17: error: called from here
  _mm_store_si128(
                 ^
In file included from /usr/lib/gcc/i586-linux-gnu/5/include/xmmintrin.h:1249:0,
                 from /usr/lib/gcc/i586-linux-gnu/5/include/x86intrin.h:31,
                 from /usr/include/i386-linux-gnu/c++/5/bits/opt_random.h:33,
                 from /usr/include/c++/5/random:50,
                 from /usr/include/c++/5/bits/stl_algo.h:66,
                 from /usr/include/c++/5/algorithm:62,
                 from prog.cpp:5:
/usr/lib/gcc/i586-linux-gnu/5/include/emmintrin.h:690:1: error: inlining failed in call to always_inline '__m128i _mm_load_si128(const __m128i*)': target specific option mismatch
 _mm_load_si128 (__m128i const *__P)
 ^
prog.cpp:42:17: error: called from here
  _mm_store_si128(
                 ^
stdout
Standard output is empty