2011-12-16 13 views
0

"ppl.h"ヘッダのConcurrency :: parallel_forアルゴリズムに関する質問があります。この例はIvor Hortonの本「Beginning Visual C++ 2010」からのものです。彼はあなたが並列計算を使用してマンデルブロ集合を構築する方法を示します。この特定の例では http://media.wiley.com/product_ancillary/83/04705008/DOWNLOAD/500880ch13.zip 「CH13/Ex13_03/Ex13_03.cpp」複数コアのプログラミング/ Mandelbrot Set/C++

:.cppのファイルを完了するために

リンク。

それはハンドル機能:

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); 
} 

基本的に、この関数はIteratePoint関数で計算されているマンデルブロ集合を描画します。

ピクセルの水平方向の行がランダムな順序でレンダリングされます。私の質問はどのくらい正確にConcurrency::parallel_forアルゴリズムがウィンドウのどの領域(つまり、yの水平行のピクセルのセット)がどのコアによってレンダリングされるかを決定する方法です。

p.s.作業例はここにあります:http://hotfile.com/dl/137661392/d63280a/MANDELBROT.rar.html

ありがとうございました!

答えて

2

parallel_forは、0とimageHeightの間のすべての値で1回lambda関数を呼び出します。効果:このように、ラムダ関数は、おそらく彼らはに実行できるように複数のワーカースレッド間の呼び出しを分割する、画像内の各yについて一度呼び出され

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

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

は同じです平行。

parallel_forはライブラリ関数なので、内部的にどのように動作するか心配する必要はありません。すべてのyに対してlamdaを1回呼び出すことを受け入れるだけです。厳密に言えば、複数のコールが同時に(例えば異なるプロセッサコア上で)発生する可能性があるため、定義された順序はありません。

+0

は私にこれをクリアするためにどうもありがとうございました) –

0

各コードのスレッドが である場合、これはコンパイラによって処理されます。コンパイラは命令をコアに配布します。

ここ

より:

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

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

+0

そうでもない、コンパイラは、コールがどのコア上で実行されている何の発言権を持っていません。 parallel_forがワーカースレッドを使用して実装されていると仮定すると、実行時にどのコアがどのコアで実行されるかはOSによって決定されます。実際には、1つのコールが複数の異なるコアで部分的に実行されることは非常に可能です。途中で払い戻された場合。プログラムを2回実行しても必ずしも毎回同じ方法でコールが配信されるわけではありません。 – zennehoy

関連する問題