mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
Merge pull request #9017 from sovrasov:parallel_for_cxx11
This commit is contained in:
commit
5f1b6ee889
@ -153,7 +153,7 @@ The first thing is to declare a custom class that inherits from @ref cv::Paralle
|
||||
`virtual void operator ()(const cv::Range& range) const`.
|
||||
|
||||
The range in the `operator ()` represents the subset of pixels that will be treated by an individual thread.
|
||||
This splitting is done automatically to distribuate equally the computation load. We have to convert the pixel index coordinate
|
||||
This splitting is done automatically to distribute equally the computation load. We have to convert the pixel index coordinate
|
||||
to a 2D `[row, col]` coordinate. Also note that we have to keep a reference on the mat image to be able to modify in-place
|
||||
the image.
|
||||
|
||||
@ -167,6 +167,11 @@ nstripes parameter in @ref cv::parallel_for_. For instance, if your processor ha
|
||||
or setting `nstripes=2` should be the same as by default it will use all the processor threads available but will split the
|
||||
workload only on two threads.
|
||||
|
||||
@note
|
||||
C++ 11 standard allows to simplify the parallel implementation by get rid of the `ParallelMandelbrot` class and replacing it with lambda expression:
|
||||
|
||||
@snippet how_to_use_OpenCV_parallel_for_.cpp mandelbrot-parallel-call-cxx11
|
||||
|
||||
Results
|
||||
-----------
|
||||
|
||||
|
@ -354,6 +354,20 @@ Cv64suf;
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* C++ 11 *
|
||||
\****************************************************************************************/
|
||||
#ifndef CV_CXX_11
|
||||
# if __cplusplus >= 201103L || defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define CV_CXX_11 1
|
||||
# endif
|
||||
#else
|
||||
# if CV_CXX_11 == 0
|
||||
# undef CV_CXX_11
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* C++ Move semantics *
|
||||
\****************************************************************************************/
|
||||
|
@ -56,6 +56,10 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include <ostream>
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@ -478,6 +482,28 @@ public:
|
||||
*/
|
||||
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
class ParallelLoopBodyLambdaWrapper : public ParallelLoopBody
|
||||
{
|
||||
private:
|
||||
std::function<void(const Range&)> m_functor;
|
||||
public:
|
||||
ParallelLoopBodyLambdaWrapper(std::function<void(const Range&)> functor) :
|
||||
m_functor(functor)
|
||||
{ }
|
||||
|
||||
virtual void operator() (const cv::Range& range) const
|
||||
{
|
||||
m_functor(range);
|
||||
}
|
||||
};
|
||||
|
||||
inline void parallel_for_(const Range& range, std::function<void(const Range&)> functor, double nstripes=-1.)
|
||||
{
|
||||
parallel_for_(range, ParallelLoopBodyLambdaWrapper(functor), nstripes);
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////// forEach method of cv::Mat ////////////////////////////
|
||||
template<typename _Tp, typename Functor> inline
|
||||
void Mat::forEach_impl(const Functor& operation) {
|
||||
|
@ -101,10 +101,35 @@ int main()
|
||||
//! [mandelbrot-transformation]
|
||||
|
||||
double t1 = (double) getTickCount();
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
|
||||
//! [mandelbrot-parallel-call-cxx11]
|
||||
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), [&](const Range& range){
|
||||
for (int r = range.start; r < range.end; r++)
|
||||
{
|
||||
int i = r / mandelbrotImg.cols;
|
||||
int j = r % mandelbrotImg.cols;
|
||||
|
||||
float x0 = j / scaleX + x1;
|
||||
float y0 = i / scaleY + y1;
|
||||
|
||||
complex<float> z0(x0, y0);
|
||||
uchar value = (uchar) mandelbrotFormula(z0);
|
||||
mandelbrotImg.ptr<uchar>(i)[j] = value;
|
||||
}
|
||||
});
|
||||
//! [mandelbrot-parallel-call-cxx11]
|
||||
|
||||
#else
|
||||
|
||||
//! [mandelbrot-parallel-call]
|
||||
ParallelMandelbrot parallelMandelbrot(mandelbrotImg, x1, y1, scaleX, scaleY);
|
||||
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), parallelMandelbrot);
|
||||
//! [mandelbrot-parallel-call]
|
||||
|
||||
#endif
|
||||
|
||||
t1 = ((double) getTickCount() - t1) / getTickFrequency();
|
||||
cout << "Parallel Mandelbrot: " << t1 << " s" << endl;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user