programming for multiple cores / Mandelbrot Set / c++

江枫思渺然 提交于 2019-12-23 05:25:49

问题


I have a question concerning the Concurrency::parallel_for algorithm of "ppl.h" header. This example is from Ivor Horton's book - "Beginning Visual C++ 2010".

Link to complete .cpp file: http://media.wiley.com/product_ancillary/83/04705008/DOWNLOAD/500880ch13.zip "Ch13/Ex13_03/Ex13_03.cpp"

In this particular example he shows how you can build the Mandelbrot Set using parallel calculations.

The function that handles it is:

void DrawSetParallelFor(HWND hWnd)
{

// setting interface here
HDC hdc(GetDC(hWnd));
RECT rect;
GetClientRect(hWnd, & rect);

// getting width and height of our window
int imageHeight(rect.bottom);
int imageWidth(rect.right);

// defining variables and constants
const double realMin(-2.1); // Minimum real value
double imaginaryMin(-1.3); // Minimum imaginary value
double imaginaryMax(+1.3); // Maximum imaginary value
double realMax(realMin+(imaginaryMax-imaginaryMin)*imageWidth/imageHeight);
double realScale((realMax-realMin)/(imageWidth-1));
double imaginaryScale((imaginaryMax-imaginaryMin)/(imageHeight-1));

// defining critical section
Concurrency::critical_section cs; // Mutex for BitBlt() operation

// starting parallel loop
Concurrency::parallel_for(0, imageHeight, [&](int y)
{
   // locking code
   cs.lock();
      HDC memDC = CreateCompatibleDC(hdc);
      HBITMAP bmp = CreateCompatibleBitmap(hdc, imageWidth, 1);
   cs.unlock();

   HGDIOBJ oldBmp = SelectObject(memDC, bmp);

   double cReal(0.0), cImaginary(0.0);
   double zReal(0.0), zImaginary(0.0);

   zImaginary = cImaginary = imaginaryMax - y*imaginaryScale;

   // filling horizontal rows with colored pixels
   for(int x = 0; x < imageWidth; ++x)
   {
      zReal = cReal = realMin + x*realScale;
      SetPixel(memDC, x, 0, Color(IteratePoint(zReal, zImaginary, cReal, cImaginary)));
   }

   // locking again 
   cs.lock();
      BitBlt(hdc, 0, y, imageWidth, 1, memDC, 0, 0, SRCCOPY);
   cs.unlock();

   // deleting objects
   SelectObject(memDC, oldBmp);
   DeleteObject(bmp);
   DeleteDC(memDC);
});

   ReleaseDC(hWnd, hdc);
}

basically this function renders the Mandelbrot Set, that is being calculated in the IteratePoint function.

horizontal rows of pixels are rendered in random order. my question is - how exactly Concurrency::parallel_for algorithm decides which region of the window (i.e. set of "y" horizontal rows of pixels) is rendered by which core.

p.s. the working example is here: http://hotfile.com/dl/137661392/d63280a/MANDELBROT.rar.html

thank you for your time!


回答1:


By the look of things, parallel_for calls the lambda function once with every value between 0 and imageHeight. Effectively:

Concurrency::parallel_for(0, imageHeight, [&](int y) {

is the same as:

for(int y=0; y<imageHeight; ++y) {

Thus, the lambda function is called once for each y in the image, possibly splitting the calls among multiple worker threads to allow them to run in parallel.

Since parallel_for is a library function, you really shouldn't worry about how it works internally. Just accept that it calls the lamda once for every y. Strictly speaking there is no defined order, since multiple calls may occur simultaneously (e.g. on different processor cores).




回答2:


This is handled by the compiler when threads for each code are generated. The compiler is responsible for distributing instructions to cores.

More here:

http://www.multicoreinfo.com/research/papers/whitepapers/intel-opti-mc.pdf

http://arco.e.ac.upc.edu/wiki/images/b/b4/Madriles_isca09.pdf



来源:https://stackoverflow.com/questions/8535404/programming-for-multiple-cores-mandelbrot-set-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!