Advertisement
dan-masek

Untitled

Dec 15th, 2017
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.83 KB | None | 0 0
  1. #include <opencv2/opencv.hpp>
  2.  
  3. #include <chrono>
  4. #include <iostream>
  5.  
  6. using std::chrono::high_resolution_clock;
  7. using std::chrono::duration_cast;
  8. using std::chrono::microseconds;
  9.  
  10. // ============================================================================
  11.  
  12. void variant_1(cv::Mat3b image, cv::Vec3f divisor)
  13. {
  14.     image.forEach(
  15.         [&divisor](cv::Vec3b& pixel, const int* po) -> void {
  16.             for (uint8_t i(0); i < 3; ++i) {
  17.                 pixel[i] = cv::saturate_cast<uint8_t>(pixel[i] / divisor[i]);
  18.             }
  19.         }
  20.     );
  21. }
  22.  
  23. // ============================================================================
  24.  
  25. class Variant2Impl : public cv::ParallelLoopBody
  26. {
  27. private:
  28.     cv::Mat3b& image_;
  29.     cv::Vec3f divisor_;
  30.  
  31. public:
  32.     Variant2Impl(cv::Mat3b& image, cv::Vec3f divisor)
  33.         : image_(image), divisor_(divisor)
  34.     {
  35.     }
  36.  
  37.     virtual void operator()(const cv::Range& range) const
  38.     {
  39.         for (int32_t i(range.start); i < range.end; ++i) {
  40.             for (cv::Vec3b& pixel : image_.row(i)) {
  41.                 for (uint8_t i(0); i < 3; ++i) {
  42.                     pixel[i] = cv::saturate_cast<uint8_t>(pixel[i] / divisor_[i]);
  43.                 }
  44.             }
  45.         }
  46.     }
  47. };
  48.  
  49. template<typename Impl>
  50. void variant_2(cv::Mat3b image, cv::Vec3f divisor)
  51. {
  52.     cv::parallel_for_(cv::Range(0, image.rows), Impl(image, divisor));
  53. }
  54.  
  55. // ============================================================================
  56.  
  57. typedef std::vector<double> times_vector;
  58. typedef std::vector<times_vector> thread_times_vector;
  59.  
  60. #define IDENTICAL_INPUT
  61.  
  62. template <typename Fn>
  63. thread_times_vector test_variant(Fn fn
  64.     , cv::Mat3b source_image
  65.     , cv::Vec3f divisor
  66.     , int32_t max_threads
  67.     , int32_t num_iterations)
  68. {
  69.     thread_times_vector times;
  70.  
  71.     for (int32_t n(0); n < max_threads; ++n) {
  72.         cv::setNumThreads(n + 1);
  73.         std::cout << cv::getNumThreads() << " ";
  74.  
  75.         times.push_back(times_vector(num_iterations));
  76.  
  77.         cv::Mat3b work_image;
  78. #ifndef IDENTICAL_INPUT
  79.         source_image.copyTo(work_image);
  80. #endif
  81.         for (int32_t i(0); i < num_iterations; ++i) {
  82. #ifdef IDENTICAL_INPUT
  83.             source_image.copyTo(work_image);
  84. #endif
  85.  
  86.             high_resolution_clock::time_point t1(high_resolution_clock::now());
  87.             fn(work_image, divisor);
  88.             high_resolution_clock::time_point t2(high_resolution_clock::now());
  89.            
  90.             times[n][i] = static_cast<double>(duration_cast<microseconds>(t2 - t1).count());
  91.         }
  92.     }
  93.  
  94.     return times;
  95. }
  96.  
  97. // ============================================================================
  98.  
  99. void print_results(std::string const& header, thread_times_vector const& times)
  100. {
  101.     std::cout << "\n" << header << "\nthreads,mean(us),min(us),max(us)\n";
  102.     for (int32_t i(0); i < times.size(); ++i) {
  103.         double mean = cv::mean(times[i])[0];
  104.         double min(0.0), max(0.0);
  105.         cv::minMaxLoc(times[i], &min, &max);
  106.         std::cout << (i + 1) << "," << mean << "," << min << "," << max << "\n";
  107.     }
  108.     std::cout << "\n";
  109. }
  110.  
  111. // ============================================================================
  112.  
  113. int main()
  114. {
  115.     cv::Mat3b source_image(cv::Mat::zeros(1024, 1024, CV_8UC3));
  116.     cv::randu(source_image, 0, 256);
  117.  
  118.     cv::Vec3f divisor(1.2f, 0.8f, 0.99f);
  119.  
  120.     int32_t MAX_THREADS(cv::getNumberOfCPUs());
  121.     int32_t NUM_ITERATIONS(1000);
  122.  
  123.     thread_times_vector t1 = test_variant(&variant_1
  124.         , source_image, divisor, MAX_THREADS, NUM_ITERATIONS);
  125.  
  126.     print_results("Variant 1", t1);
  127.  
  128.     thread_times_vector t2 = test_variant(&variant_2<Variant2Impl>
  129.         , source_image, divisor, MAX_THREADS, NUM_ITERATIONS);
  130.  
  131.     print_results("Variant 2", t2);
  132. }
  133.  
  134. // ============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement