Guest User

Untitled

a guest
Aug 23rd, 2019
94
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. c++ --version; c++ -std=c++14 -g stlcost.cpp && ./a.out && rm ./a.out
  3. Apple LLVM version 10.0.1 (clang-1001.0.46.4)
  4. Target: x86_64-apple-darwin18.6.0
  5. Thread model: posix
  6. InstalledDir: /Library/Developer/CommandLineTools/usr/bin
  7.  
  8. iteration 0 -----------------------------------------
  9.  
  10. malloc():
  11. InitImage: 6.111393 ms
  12. MakeMips: 5.444773 ms
  13.  
  14. std::array:
  15. InitImage: 5.191247 ms (0.85x)
  16. MakeMips: 21.877937 ms (4x)
  17.  
  18. std::vector:
  19. InitImage: 31.074629 ms (5.1x)
  20. MakeMips: 22.224956 ms (4.1x)
  21.  
  22. iteration 1 -----------------------------------------
  23.  
  24. malloc():
  25. InitImage: 16.152593 ms (2.6x)
  26. MakeMips: 15.258340 ms (2.8x)
  27.  
  28. std::array:
  29. InitImage: 6.697883 ms (1.1x)
  30. MakeMips: 29.992644 ms (5.5x)
  31.  
  32. std::vector:
  33. InitImage: 61.089039 ms (10x)
  34. MakeMips: 34.484021 ms (6.3x)
  35.  
  36. iteration 2 -----------------------------------------
  37.  
  38. malloc():
  39. InitImage: 2.333101 ms (0.38x)
  40. MakeMips: 5.921506 ms (1.1x)
  41.  
  42. std::array:
  43. InitImage: 16.481657 ms (2.7x)
  44. MakeMips: 20.485178 ms (3.8x)
  45.  
  46. std::vector:
  47. InitImage: 27.512777 ms (4.5x)
  48. MakeMips: 18.223748 ms (3.3x)
  49. */
  50.  
  51. ///usr/bin/env \
  52. [ -n "${PATHEXT}" ] && ext='.exe'; \
  53. bin="$(dirname $0)/$(basename ${0%.*})$ext"; \
  54. c++ -std=c++14 -g -Werror -o $bin $0 \
  55. && $bin "$@"; \
  56. status=$?; \
  57. rm $bin; \
  58. exit $status
  59.  
  60. // the size of the image that is made into mips
  61. #define IMAGE_SIZE() 512
  62.  
  63. typedef float ChannelType;
  64.  
  65. #include <stdio.h>
  66. #include <array>
  67. #include <vector>
  68. #include <chrono>
  69.  
  70. struct ScopedTimer
  71. {
  72. ScopedTimer(double& baseline, const char* label)
  73. : m_baseline(baseline)
  74. {
  75. printf("%s: ", label);
  76. m_start = std::chrono::high_resolution_clock::now();
  77. }
  78.  
  79. ~ScopedTimer()
  80. {
  81. std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
  82. std::chrono::duration<double> duration = std::chrono::duration_cast<std::chrono::duration<double>>(end - m_start);
  83. const double elapsed = duration.count();
  84. if (m_baseline == 0) {
  85. printf("%f ms\n", elapsed * 1000.0);
  86. m_baseline = elapsed;
  87. } else {
  88. printf("%f ms (%0.2gx)\n", elapsed * 1000.0, elapsed / m_baseline);
  89. }
  90. }
  91.  
  92. std::chrono::high_resolution_clock::time_point m_start;
  93. double& m_baseline;
  94. };
  95.  
  96. // calculate the total number of pixels needed to hold the image of size IMAGE_SIZE() as well as all the mips
  97. constexpr size_t TotalPixelsMipped()
  98. {
  99. size_t ret = 0;
  100. size_t size = IMAGE_SIZE();
  101. while (size)
  102. {
  103. ret += size * size;
  104. size /= 2;
  105. }
  106. return ret;
  107. }
  108.  
  109. constexpr size_t TotalChannelsMipped()
  110. {
  111. // RGBA
  112. return TotalPixelsMipped() * 4;
  113. }
  114.  
  115. constexpr size_t NumMips()
  116. {
  117. size_t ret = 0;
  118. size_t size = IMAGE_SIZE();
  119. while (size)
  120. {
  121. ret++;
  122. size /= 2;
  123. }
  124. return ret;
  125. }
  126.  
  127. void GetMipInfo(size_t desiredMipIndex, size_t& offset, size_t& width)
  128. {
  129. offset = 0;
  130. width = IMAGE_SIZE();
  131.  
  132. for (size_t mipIndex = 0; mipIndex < desiredMipIndex; ++mipIndex)
  133. {
  134. offset += width * width * 4;
  135. width /= 2;
  136. }
  137. }
  138.  
  139. template<typename T>
  140. void MakeMip(T& image, size_t mipIndex)
  141. {
  142. size_t srcOffset;
  143. size_t srcWidth;
  144. GetMipInfo(mipIndex - 1, srcOffset, srcWidth);
  145.  
  146. size_t destOffset;
  147. size_t destWidth;
  148. GetMipInfo(mipIndex, destOffset, destWidth);
  149.  
  150. for (size_t destY = 0; destY < destWidth; ++destY)
  151. {
  152. for (size_t destX = 0; destX < destWidth; ++destX)
  153. {
  154. for (size_t channel = 0; channel < 4; ++channel)
  155. {
  156. // 2x2 box filter source mip pixels
  157. float value =
  158. float(image[((destY * 2 + 0) * srcWidth + destX * 2 + 0) * 4 + srcOffset] + channel) +
  159. float(image[((destY * 2 + 0) * srcWidth + destX * 2 + 1) * 4 + srcOffset] + channel) +
  160. float(image[((destY * 2 + 1) * srcWidth + destX * 2 + 0) * 4 + srcOffset] + channel) +
  161. float(image[((destY * 2 + 1) * srcWidth + destX * 2 + 1) * 4 + srcOffset] + channel);
  162. image[destOffset] = ChannelType(value / 4.0f);
  163. destOffset++;
  164. }
  165. }
  166. }
  167. }
  168.  
  169. template<typename T>
  170. void MakeMips(T& image)
  171. {
  172. size_t mipCount = NumMips();
  173. for (size_t mipIndex = 1; mipIndex < mipCount; ++mipIndex)
  174. MakeMip(image, mipIndex);
  175. }
  176.  
  177. template<typename T>
  178. void InitImage(T& image)
  179. {
  180. memset(&image[0], 0, TotalChannelsMipped() * sizeof(ChannelType));
  181.  
  182. // It doesn't matter what we put into the image since we aren't ever looking at it, but initializing it anyhow.
  183. size_t i = 0;
  184. for (size_t y = 0; y < IMAGE_SIZE(); ++y)
  185. {
  186. for (size_t x = 0; x < IMAGE_SIZE(); ++x)
  187. {
  188. image[i * 4 + 0] = ChannelType(x % 256);
  189. image[i * 4 + 1] = ChannelType(y % 256);
  190. image[i * 4 + 2] = ChannelType(0);
  191. image[i * 4 + 3] = ChannelType(255);
  192. i++;
  193. }
  194. }
  195. }
  196.  
  197. int main(void)
  198. {
  199.  
  200. double init_image_baseline = 0, make_mips_baseline = 0;
  201.  
  202. for (int i = 0; i < 3; ++i){
  203.  
  204. printf("\niteration %i -----------------------------------------\n", i);
  205.  
  206. // c array
  207. {
  208. ChannelType* carray;
  209. printf("\nmalloc():\n");
  210. {
  211. ScopedTimer timer(init_image_baseline, "InitImage");
  212. carray = (ChannelType*)malloc(sizeof(ChannelType)*TotalChannelsMipped());
  213. InitImage(carray);
  214. }
  215. {
  216. ScopedTimer timer(make_mips_baseline, "MakeMips");
  217. MakeMips(carray);
  218. }
  219. free(carray);
  220. }
  221.  
  222. // std::array
  223. // dynamically allocated to avoid a stack overflow
  224. {
  225. std::array<ChannelType, TotalChannelsMipped()>* array_ptr = new std::array<ChannelType, TotalChannelsMipped()>;
  226. std::array<ChannelType, TotalChannelsMipped()>& array = *array_ptr;
  227. printf("\nstd::array:\n");
  228. {
  229. ScopedTimer timer(init_image_baseline, "InitImage");
  230. InitImage(array);
  231. }
  232. {
  233. ScopedTimer timer(make_mips_baseline, "MakeMips");
  234. MakeMips(array);
  235. }
  236. delete(array_ptr);
  237. }
  238.  
  239. // std::vector
  240. {
  241. std::vector<ChannelType> vector;
  242. printf("\nstd::vector:\n");
  243. {
  244. ScopedTimer timer(init_image_baseline, "InitImage");
  245. vector.resize(TotalChannelsMipped());
  246. InitImage(vector);
  247. }
  248. {
  249. ScopedTimer timer(make_mips_baseline, "MakeMips");
  250. MakeMips(vector);
  251. }
  252. }
  253. }
  254.  
  255. #ifdef _MSC_VER
  256. system("pause");
  257. #endif
  258. return 0;
  259. }
RAW Paste Data