SHARE
TWEET

Untitled

a guest Aug 23rd, 2019 65 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top