簡體   English   中英

我可以用openmp迭代C ++ 11 std :: tuple嗎?

[英]Can I iterate over a C++11 std::tuple with openmp?

我有以下代碼來迭代std::tuple 代碼來自這里

#include <tuple>
#include <utility>

template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(std::tuple<Tp...> &, FuncT) // Unused arguments are given no names.
{ }

template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>& t, FuncT& f)
{
    f(std::get<I>(t));
    for_each<I + 1, FuncT, Tp...>(t, f);
}

現在,我想執行這個for_each使用OpenMP循環,以同樣的方式,我可以使用OpenMP的上for 有沒有辦法讓這成為可能?

注意:您可以修改上述代碼或使用您自己的for_each任何其他版本。

C ++ 11模板語法對我來說非常陌生,但是像這樣的遞歸問題最好使用顯式OpenMP任務並行:

template<std::size_t I = 0, typename FuncT, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(std::tuple<Tp...>& t, FuncT& f)
{
    #pragma omp task firstprivate(I) shared(t,f)
    {
        f(std::get<I>(t));
    }
    for_each<I + 1, FuncT, Tp...>(t, f);
}

...

// Proper usage
#pragma omp parallel
{
    #pragma omp single
    for_each(...);
}

重要的部分是在parallel區域內的single構造中調用for_each 因此,只有一個線程會調用for_each ,這反過來會導致f(std::get<I>(t)); 排隊等待以后執行作為顯式任務。 其他線程在single構造末尾的隱式屏障處等待時,將開始從任務隊列中拉出任務並並行執行它們,直到隊列為空。 為清楚起見,明確給出了任務使用的所有變量的共享類。

應該共享tf引用的對象,並且引用本身(實際上是實現引用的指針)應該是firstprivate。 另一方面,OpenMP標准禁止引用類型為firstprivate,不同的編譯器供應商傾向於以不同方式實現該標准。 英特爾C ++編譯器接受以下代碼,它在任務內部提供正確的結果,但引用的變量是私有化的(這是錯誤的):

void f(int& p)
{
   #pragma omp task
   {
      cout << "p = " << p << endl;
      p = 3;
      cout << "p' = " << p << endl;
   }
}

void f1()
{
   int i = 5;

   #pragma omp parallel
   {
      #pragma omp single
      f(i);
   }
   cout << "i = " << i << endl;
}

PGI的編譯器給出了正確的結果,並沒有私有化i 另一方面,GCC正確地確定p應該是firstprivate但是然后進入標准中的禁止並且給出編譯時錯誤。

如果將任務修改為:

#pragma omp task shared(p)
{
    ...
}

它可以正常使用GCC但是任務打印錯誤的初始值p然后導致英特爾C ++編譯器和PGI的C ++編譯器出現分段錯誤。

去搞清楚!

暫無
暫無

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

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