gtc_integer.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #define GLM_ENABLE_EXPERIMENTAL
  2. #define GLM_FORCE_INLINE
  3. #include <glm/gtc/epsilon.hpp>
  4. #include <glm/gtc/integer.hpp>
  5. #include <glm/gtc/type_precision.hpp>
  6. #include <glm/gtc/vec1.hpp>
  7. #include <glm/gtx/type_aligned.hpp>
  8. #include <glm/vector_relational.hpp>
  9. #include <glm/vec2.hpp>
  10. #include <glm/vec3.hpp>
  11. #include <glm/vec4.hpp>
  12. #include <ctime>
  13. #include <cstdio>
  14. #include <vector>
  15. #include <cmath>
  16. namespace log2_
  17. {
  18. static int test()
  19. {
  20. int Error = 0;
  21. int A0 = static_cast<int>(glm::log2(16.f));
  22. glm::ivec1 B0(glm::log2(glm::vec1(16.f)));
  23. glm::ivec2 C0(glm::log2(glm::vec2(16.f)));
  24. glm::ivec3 D0(glm::log2(glm::vec3(16.f)));
  25. glm::ivec4 E0(glm::log2(glm::vec4(16.f)));
  26. int A1 = glm::log2(int(16));
  27. glm::ivec1 B1 = glm::log2(glm::ivec1(16));
  28. glm::ivec2 C1 = glm::log2(glm::ivec2(16));
  29. glm::ivec3 D1 = glm::log2(glm::ivec3(16));
  30. glm::ivec4 E1 = glm::log2(glm::ivec4(16));
  31. Error += A0 == A1 ? 0 : 1;
  32. Error += glm::all(glm::equal(B0, B1)) ? 0 : 1;
  33. Error += glm::all(glm::equal(C0, C1)) ? 0 : 1;
  34. Error += glm::all(glm::equal(D0, D1)) ? 0 : 1;
  35. Error += glm::all(glm::equal(E0, E1)) ? 0 : 1;
  36. glm::uint64 A2 = glm::log2(glm::uint64(16));
  37. glm::u64vec1 B2 = glm::log2(glm::u64vec1(16));
  38. glm::u64vec2 C2 = glm::log2(glm::u64vec2(16));
  39. glm::u64vec3 D2 = glm::log2(glm::u64vec3(16));
  40. glm::u64vec4 E2 = glm::log2(glm::u64vec4(16));
  41. Error += A2 == glm::uint64(4) ? 0 : 1;
  42. Error += glm::all(glm::equal(B2, glm::u64vec1(4))) ? 0 : 1;
  43. Error += glm::all(glm::equal(C2, glm::u64vec2(4))) ? 0 : 1;
  44. Error += glm::all(glm::equal(D2, glm::u64vec3(4))) ? 0 : 1;
  45. Error += glm::all(glm::equal(E2, glm::u64vec4(4))) ? 0 : 1;
  46. return Error;
  47. }
  48. static int perf(std::size_t Count)
  49. {
  50. int Error = 0;
  51. #if GLM_COMPILER & GLM_COMPILER_CLANG
  52. # pragma clang diagnostic push
  53. # pragma clang diagnostic ignored "-Wsign-conversion"
  54. #endif
  55. {
  56. std::vector<int> Result;
  57. Result.resize(Count);
  58. std::clock_t Begin = clock();
  59. for(int i = 0; i < static_cast<int>(Count); ++i)
  60. Result[i] = glm::log2(static_cast<int>(i));
  61. std::clock_t End = clock();
  62. std::printf("glm::log2<int>: %d clocks\n", static_cast<int>(End - Begin));
  63. }
  64. {
  65. std::vector<glm::ivec4> Result;
  66. Result.resize(Count);
  67. std::clock_t Begin = clock();
  68. for(int i = 0; i < static_cast<int>(Count); ++i)
  69. Result[i] = glm::log2(glm::ivec4(i));
  70. std::clock_t End = clock();
  71. std::printf("glm::log2<ivec4>: %d clocks\n", static_cast<int>(End - Begin));
  72. }
  73. #if GLM_COMPILER & GLM_COMPILER_CLANG
  74. # pragma clang diagnostic pop
  75. #endif
  76. # if GLM_HAS_BITSCAN_WINDOWS
  77. {
  78. std::vector<glm::ivec4> Result;
  79. Result.resize(Count);
  80. std::clock_t Begin = clock();
  81. #if GLM_COMPILER& GLM_COMPILER_VC
  82. # pragma warning(push)
  83. # pragma warning(disable: 4267)
  84. #endif
  85. for(std::size_t i = 0; i < Count; ++i)
  86. {
  87. glm::vec<4, unsigned long, glm::defaultp> Tmp;
  88. _BitScanReverse(&Tmp.x, i);
  89. _BitScanReverse(&Tmp.y, i);
  90. _BitScanReverse(&Tmp.z, i);
  91. _BitScanReverse(&Tmp.w, i);
  92. Result[i] = glm::ivec4(Tmp);
  93. }
  94. #if GLM_COMPILER & GLM_COMPILER_VC
  95. # pragma warning(pop)
  96. #endif
  97. std::clock_t End = clock();
  98. std::printf("glm::log2<ivec4> inlined: %d clocks\n", static_cast<int>(End - Begin));
  99. }
  100. {
  101. std::vector<glm::vec<4, unsigned long, glm::defaultp> > Result;
  102. Result.resize(Count);
  103. std::clock_t Begin = clock();
  104. #if GLM_COMPILER& GLM_COMPILER_VC
  105. # pragma warning(push)
  106. # pragma warning(disable: 4267)
  107. #endif
  108. for(std::size_t i = 0; i < Count; ++i)
  109. {
  110. _BitScanReverse(&Result[i].x, i);
  111. _BitScanReverse(&Result[i].y, i);
  112. _BitScanReverse(&Result[i].z, i);
  113. _BitScanReverse(&Result[i].w, i);
  114. }
  115. #if GLM_COMPILER & GLM_COMPILER_VC
  116. # pragma warning(pop)
  117. #endif
  118. std::clock_t End = clock();
  119. std::printf("glm::log2<ivec4> inlined no cast: %d clocks\n", static_cast<int>(End - Begin));
  120. }
  121. {
  122. std::vector<glm::ivec4> Result;
  123. Result.resize(Count);
  124. std::clock_t Begin = clock();
  125. #if GLM_COMPILER& GLM_COMPILER_VC
  126. # pragma warning(push)
  127. # pragma warning(disable: 4267)
  128. #endif
  129. for(std::size_t i = 0; i < Count; ++i)
  130. {
  131. _BitScanReverse(reinterpret_cast<unsigned long*>(&Result[i].x), i);
  132. _BitScanReverse(reinterpret_cast<unsigned long*>(&Result[i].y), i);
  133. _BitScanReverse(reinterpret_cast<unsigned long*>(&Result[i].z), i);
  134. _BitScanReverse(reinterpret_cast<unsigned long*>(&Result[i].w), i);
  135. }
  136. #if GLM_COMPILER & GLM_COMPILER_VC
  137. # pragma warning(pop)
  138. #endif
  139. std::clock_t End = clock();
  140. std::printf("glm::log2<ivec4> reinterpret: %d clocks\n", static_cast<int>(End - Begin));
  141. }
  142. # endif//GLM_HAS_BITSCAN_WINDOWS
  143. #if GLM_COMPILER & GLM_COMPILER_CLANG
  144. # pragma clang diagnostic push
  145. # pragma clang diagnostic ignored "-Wsign-conversion"
  146. #endif
  147. {
  148. std::vector<float> Result;
  149. Result.resize(Count);
  150. std::clock_t Begin = clock();
  151. for(std::size_t i = 0; i < Count; ++i)
  152. Result[i] = glm::log2(static_cast<float>(i));
  153. std::clock_t End = clock();
  154. std::printf("glm::log2<float>: %d clocks\n", static_cast<int>(End - Begin));
  155. }
  156. #if GLM_COMPILER & GLM_COMPILER_CLANG
  157. # pragma clang diagnostic pop
  158. #endif
  159. #if GLM_COMPILER & GLM_COMPILER_CLANG
  160. # pragma clang diagnostic push
  161. # pragma clang diagnostic ignored "-Wsign-conversion"
  162. #endif
  163. {
  164. std::vector<glm::vec4> Result;
  165. Result.resize(Count);
  166. std::clock_t Begin = clock();
  167. for(int i = 0; i < static_cast<int>(Count); ++i)
  168. Result[i] = glm::log2(glm::vec4(static_cast<float>(i)));
  169. std::clock_t End = clock();
  170. std::printf("glm::log2<vec4>: %d clocks\n", static_cast<int>(End - Begin));
  171. }
  172. #if GLM_COMPILER & GLM_COMPILER_CLANG
  173. # pragma clang diagnostic pop
  174. #endif
  175. return Error;
  176. }
  177. }//namespace log2_
  178. namespace iround
  179. {
  180. static int test()
  181. {
  182. int Error = 0;
  183. for(float f = 0.0f; f < 3.1f; f += 0.05f)
  184. {
  185. int RoundFast = static_cast<int>(glm::iround(f));
  186. int RoundSTD = static_cast<int>(glm::round(f));
  187. Error += RoundFast == RoundSTD ? 0 : 1;
  188. assert(!Error);
  189. }
  190. return Error;
  191. }
  192. }//namespace iround
  193. namespace uround
  194. {
  195. static int test()
  196. {
  197. int Error = 0;
  198. for(float f = 0.0f; f < 3.1f; f += 0.05f)
  199. {
  200. int RoundFast = static_cast<int>(glm::uround(f));
  201. int RoundSTD = static_cast<int>(glm::round(f));
  202. Error += RoundFast == RoundSTD ? 0 : 1;
  203. assert(!Error);
  204. }
  205. return Error;
  206. }
  207. }//namespace uround
  208. int main()
  209. {
  210. int Error(0);
  211. Error += ::log2_::test();
  212. Error += ::iround::test();
  213. Error += ::uround::test();
  214. std::size_t const Samples(1000);
  215. Error += ::log2_::perf(Samples);
  216. return Error;
  217. }