代码之家  ›  专栏  ›  技术社区  ›  Peter

如何从不同线程写入文件,OpenMP,C++

  •  2
  • Peter  · 技术社区  · 7 年前

    我使用openMP来并行我的C++程序。我的并行代码的形式非常简单

    #pragma omp parallel for shared(a, b, c) private(i, result)
            for (i = 0; i < N; i++){
             result= F(a,b,c,i)//do some calculation
             cout<<i<<" "<<result<<endl;
             }
    

    我怎样才能解决这个问题?

    2 回复  |  直到 7 年前
        1
  •  9
  •   Claude    7 年前

    OpenMP提供了pragmas来帮助同步。 #pragma omp critical 任何时候只允许一个线程执行附加语句(互斥临界区域)。这个 #pragma omp ordered

    // g++ -std=c++11 -Wall -Wextra -pedantic -fopenmp critical.cpp
    #include <iostream>
    
    int main()
    {
      #pragma omp parallel for
      for (int i = 0; i < 20; ++i)
        std::cout << "unsynchronized(" << i << ") ";
      std::cout << std::endl;
      #pragma omp parallel for
      for (int i = 0; i < 20; ++i)
        #pragma omp critical
        std::cout << "critical(" << i << ") ";
      std::cout << std::endl;
      #pragma omp parallel for ordered
      for (int i = 0; i < 20; ++i)
        #pragma omp ordered
        std::cout << "ordered(" << i << ") ";
      std::cout << std::endl;
      return 0;
    }
    

    示例输出(通常每次不同):

    unsynchronized(unsynchronized(unsynchronized(05) unsynchronized() 6unsynchronized() 1unsynchronized(7) ) unsynchronized(unsynchronized(28) ) unsynchronized(unsynchronized(93) ) unsynchronized(4) 10) unsynchronized(11) unsynchronized(12) unsynchronized(15) unsynchronized(16unsynchronized() 13unsynchronized() 17) unsynchronized(unsynchronized(18) 14unsynchronized() 19) 
    critical(5) critical(0) critical(6) critical(15) critical(1) critical(10) critical(7) critical(16) critical(2) critical(8) critical(17) critical(3) critical(9) critical(18) critical(11) critical(4) critical(19) critical(12) critical(13) critical(14) 
    ordered(0) ordered(1) ordered(2) ordered(3) ordered(4) ordered(5) ordered(6) ordered(7) ordered(8) ordered(9) ordered(10) ordered(11) ordered(12) ordered(13) ordered(14) ordered(15) ordered(16) ordered(17) ordered(18) ordered(19) 
    
        2
  •  1
  •   Aconcagua    7 年前

    问题是:您有一个所有线程都试图访问的资源。必须保护这些单一资源不受并发访问(线程安全资源也这样做,只是对您透明;顺便说一句: here 是关于std::cout的线程安全性的一个很好的答案。您现在可以保护这一单一资源,例如使用 std::mutex . 然后问题是,线程必须等待互斥体,直到另一个线程再次返回互斥体。因此,只有当F是a时,才能从并行化中获益 非常 复杂函数。

    如果我可以假设您希望在较大I的结果之前得到较小I的F(…I)的结果,那么您应该完全放弃并行化,或者以不同的方式进行:

    提供大小数组 N 然后让每个线程将其结果存储在那里( array[i] = f(i); ). 然后在一个单独的非并行循环中迭代数组。同样,只有在以下情况下,这样做才值得付出努力 F