簡體   English   中英

帶有私有和共享子句的C ++ OpenMP計算錯誤

[英]C++ OpenMP computation errors with private and shared clause

我有一個與OpenMP並行化的for循環,但是有多個計算錯誤,可能是由於我對OpenMP多線程概念的了解不足:

for ( int i = -X/2; i < X/2; ++i )
{
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
}

這工作正常,然后進行了以下更改:

#pragma omp parallel for shared (buffer, response) private(base, temp)
for ( int i = -X/2; i < X/2; ++i )
{
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
}

在此代碼中, buffer.yresponse都不具有正確的值。 以我的理解,每個線程都應該有一個自己的base.ytemp副本,它們只是用於計算的臨時變量,並且必須共享bufferresponse (它們將存儲計算出的數據),但這不能作為我希望。

唯一理想的版本是以下版本,但顯然並沒有提高性能:

omp_lock_t writelock;
omp_init_lock(&writelock);
omp_set_num_threads (4);

#pragma omp parallel for
for ( int i = -X/2; i < X/2; ++i )
{
    omp_set_lock(&writelock);
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
    omp_unset_lock(&writelock);
}
omp_destroy_lock(&writelock);

可能是什么問題? anchorrho_step在此循環中是常量)

為了使您的代碼能夠處理bufferresponse變量的跨線程,您需要為它們使用一些每個線程的局部變量,並對它們進行最后的歸約以更新其共享的對應變量。

這是它的外觀(未經測試):

#pragma omp parallel firstprivate( base )
{
    auto localResponse = response;
    auto localBuffer = buffer;
    #pragma omp for
    for ( int i = -X/2; i < X/2; ++i )
    {
        base.y = anchor + i * rho_step;
        auto temp = some_function( base );
        if ( temp > localResponse )
        {
            localBuffer.y = base.y;
            localResponse = temp;
        }
    }
    #pragma omp critical
    {
        if ( localResponse > response )
        {
            buffer.y = localBuffer.y;
            response = localResponse;
        }
    }
}

暫無
暫無

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

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