簡體   English   中英

如何在openmp中並行化while while和while循環?

[英]How to parallelize do while and while loop in openmp?

我正在嘗試使用OpenMP學習並行編程,我感興趣的是並行化以下do while循環,其中包含幾個while循環:

do {
        while(left < (length - 1) && data[left] <= pivot) left++;
        while(right > 0 && data[right] >= pivot) right--;

        /* swap elements */
        if(left < right){
            temp = data[left];
            data[left] = data[right];
            data[right] = temp;
        }

    } while(left < right);

我實際上並沒有想出如何並行化whiledo while循環,找不到任何資源,它專門描述了如何並行化whiledo while循環。 我已經找到了指令for循環,但我不能做任何假設whiledo while從循環。 那么,請你描述我如何並行化我在這里提供的循環?

編輯

我已將do while循環轉換為以下代碼,其中僅使用for循環。

for(i = 1; i<length-1; i++)
{
    if(data[left] > pivot)
    {
        i = length;
    }
    else
    {
        left = i;
    }

}

for(j=length-1; j > 0; j--)
{
    if(data[right] < pivot)
    {
        j = 0;
    }
    else
    {
        right = j;
    }
}

/* swap elements */
if(left < right)
{
    temp = data[left];
    data[left] = data[right];
    data[right] = temp;
}

int leftCopy = left;
int rightCopy = right;

for(int leftCopy = left; leftCopy<right;leftCopy++)
{
    for(int new_i = left; new_i<length-1; new_i++)
    {
        if(data[left] > pivot)
        {
            new_i = length;
        }
        else
        {
            left = new_i;
        }
    }

    for(int new_j=right; new_j > 0; new_j--)
    {
        if(data[right] < pivot)
        {
            new_j = 0;
        }
        else
        {
            right = new_j;
        }
    }
    leftCopy = left;
    /* swap elements */
    if(left < right)
    {
        temp = data[left];
        data[left] = data[right];
        data[right] = temp;
    }
}

此代碼工作正常並產生正確的結果,但是當我嘗試並行化上述代碼的部分時,通過將前兩個for循環更改為以下內容:

#pragma omp parallel default(none) firstprivate(left) private(i,tid) shared(length, pivot, data)
    {
#pragma omp for
        for(i = 1; i<length-1; i++)
        {
            if(data[left] > pivot)
            {
                i = length;
            }
            else
            {
                left = i;
            }
        }
    }


#pragma omp parallel default(none) firstprivate(right) private(j) shared(length, pivot, data)
    {
#pragma omp for
        for(j=length-1; j > 0; j--)
        {
            if(data[right] < pivot)
            {
                j = 0;
            }
            else
            {
                right = j;
            }
        }
    }

速度比非並行化代碼差。 請幫我確定一下我的問題。

謝謝

首先,排序算法很難與OpenMP並行循環並行化。 這是因為循環跳閘計數不是確定性的,而是取決於每次迭代讀取的輸入設置值。

我不認為有data[left] <= pivot這樣的循環條件會運行良好,因為OpenMP庫並不確切知道如何在線程之間對迭代空間進行分區。

如果您仍然對並行排序算法感興趣,我建議您先閱讀文獻,看看那些由於其可擴展性而真正值得實施的算法。 如果您只是想學習OpenMP,我建議您從更簡單的算法開始,例如bucket-sort ,其中桶的數量眾所周知且不經常更改。

關於您嘗試並行化的示例, while OpenMP不直接支持循環,因為迭代次數(循環行程計數)不是確定性的(否則,很容易將它們轉換為for循環)。 因此,不可能在線程之間分配迭代。 此外,while循環通常使用最后一次迭代的結果來檢查條件。 這稱為Read-after-Writetrue-dependency ,無法並行化。

如果您嘗試最小化omp parallel子句的數量,則可能會減輕您的減速問題。 另外,嘗試將它們移出所有循環。 這些子句可以創建和連接在代碼的並行部分中使用的附加線程,這是昂貴的。

您仍然可以在並行塊內同步線程,因此結果類似。 事實上,默認情況下,所有線程都在omp for子句的末尾相互等待,這樣就可以更容易了。

#pragma omp parallel default(none) firstprivate(right,left) private(i,j) shared(length, pivot, data)
{
    #pragma omp for
    for(i = 1; i<length-1; i++)
    {
        if(data[left] > pivot)
        {
            i = length;
        }
        else
        {
            left = i;
        }
    }

    #pragma omp for 
    for(j=length-1; j > 0; j--)
    {
        if(data[right] < pivot)
        {
            j = 0;
        }
        else
        {
            right = j;
        }
    }
} // end omp parallel 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM