0

次の関数を OpenMP で並列化したい:

void calculateAll() {
int k;
int nodeId1, minCost1, lowerLimit1, upperLimit8;
for (k = mostUpperLevel; k > 0; k--) {
    int myStart = borderNodesArrayStartGlobal[k - 1];
    int size = myStart + borderNodesArraySizeGlobal[k - 1];
/* this loop may be parallel */    
for (nodeId1 = myStart; nodeId1 < size; nodeId1++) {
        if (getNodeScanned(nodeId1)) {
            setNodeScannedFalse(nodeId1);
        } else {
            minCost1 = myMax;
            lowerLimit1 = getNode3LevelsDownAll(nodeId1);
            upperLimit8 = getUpperLimit3LevelsDownAll(nodeId1);
            changeNodeValue(nodeId1, lowerLimit1, upperLimit8, minCost1, minCost1);
        }
    }
}

int myStart = restNodesArrayStartGlobal;
int size = myStart + restNodesArraySizeGlobal;
/* this loop may also be parallel */  
for (nodeId1 = myStart; nodeId1 < size; nodeId1++) {
    if (getNodeScanned(nodeId1)) {
        setNodeScannedFalse(nodeId1);
    } else {
        minCost1 = myMax;
        lowerLimit1 = getNode3LevelsDownAll(nodeId1);
        upperLimit8 = getUpperLimit3LevelsDownAll(nodeId1);
        changeNodeValue(nodeId1, lowerLimit1, upperLimit8, minCost1, minCost1);
    }
}
}

2 つの内部ループで「omp pragma parallel for」を使用できますが、新しいスレッドを作成するための一定のオーバーヘッドが原因で、コードが遅すぎます。「omp pragma parallel」を分離して、関数の先頭で必要なスレッドを取得し、次に「omp pragma for」を使用して最良の結果を得る方法はありますか? gcc 4.6 を使用しています。

前もって感謝します

4

1 に答える 1

0

スレッドの作成は通常、openmp プログラムのボトルネックではありません。スレッドへのタスクの分散です。スレッドは最初に実際に生成されます ( VTune#pragma omp forなどのプロファイラーで確認できます。各ループで作業がスレッドに割り当てられます。これはコストのかかる操作であるため、この割り当てはしばしば問題になります。

ただし、スケジューラをいじってみる必要があります。これはパフォーマンスに大きな影響を与える可能性があるためです。たとえば、schedule(dynamic,chunksize)vsschedule(static,chunksize)で遊んだり、さまざまなチャンクサイズを試したりします。

于 2013-01-22T21:04:29.480 に答える