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`.
|
`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.
|
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
|
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.
|
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
|
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.
|
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
|
Results
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -354,6 +354,20 @@ Cv64suf;
|
|||||||
#endif
|
#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 *
|
* C++ Move semantics *
|
||||||
\****************************************************************************************/
|
\****************************************************************************************/
|
||||||
|
@ -56,6 +56,10 @@
|
|||||||
#include "opencv2/core.hpp"
|
#include "opencv2/core.hpp"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
#ifdef CV_CXX_11
|
||||||
|
#include <functional>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -478,6 +482,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
|
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 ////////////////////////////
|
/////////////////////////////// forEach method of cv::Mat ////////////////////////////
|
||||||
template<typename _Tp, typename Functor> inline
|
template<typename _Tp, typename Functor> inline
|
||||||
void Mat::forEach_impl(const Functor& operation) {
|
void Mat::forEach_impl(const Functor& operation) {
|
||||||
|
@ -101,10 +101,35 @@ int main()
|
|||||||
//! [mandelbrot-transformation]
|
//! [mandelbrot-transformation]
|
||||||
|
|
||||||
double t1 = (double) getTickCount();
|
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]
|
//! [mandelbrot-parallel-call]
|
||||||
ParallelMandelbrot parallelMandelbrot(mandelbrotImg, x1, y1, scaleX, scaleY);
|
ParallelMandelbrot parallelMandelbrot(mandelbrotImg, x1, y1, scaleX, scaleY);
|
||||||
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), parallelMandelbrot);
|
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), parallelMandelbrot);
|
||||||
//! [mandelbrot-parallel-call]
|
//! [mandelbrot-parallel-call]
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
t1 = ((double) getTickCount() - t1) / getTickFrequency();
|
t1 = ((double) getTickCount() - t1) / getTickFrequency();
|
||||||
cout << "Parallel Mandelbrot: " << t1 << " s" << endl;
|
cout << "Parallel Mandelbrot: " << t1 << " s" << endl;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user