C++ 使用OpenMP并行化内部循环

C++ 使用OpenMP并行化内部循环,c++,multithreading,openmp,C++,Multithreading,Openmp,假设我们有两个嵌套循环。内部循环应该并行化,但外部循环需要按顺序执行。那么下面的代码就是我们想要的: for (int i = 0; i < N; ++i) { #pragma omp parallel for schedule(static) for (int j = first(i); j < last(i); ++j) { // Do some work } } for(int i=0;i

假设我们有两个嵌套循环。内部循环应该并行化,但外部循环需要按顺序执行。那么下面的代码就是我们想要的:

for (int i = 0; i < N; ++i) {
  #pragma omp parallel for schedule(static)
  for (int j = first(i); j < last(i); ++j) {
    // Do some work
  }
}
for(int i=0;i
现在假设每个线程都必须获得一些线程本地对象来执行内部循环中的工作,并且获取这些线程本地对象的成本很高。因此,我们不希望执行以下操作:

for (int i = 0; i < N; ++i) {
  #pragma omp parallel for schedule(static)
  for (int j = first(i); j < last(i); ++j) {
    ThreadLocalObject &obj = GetTLO(omp_get_thread_num()); // Costly!
    // Do some work with the help of obj
  }
}
for(int i=0;i
我如何解决这个问题

  • 每个线程应该只请求其本地对象一次

  • 内部循环应该在所有线程之间并行

  • 外部循环的迭代应该一个接一个地执行

  • 我的想法如下,但它真的想要我想要的吗

    #pragma omp parallel
    {
      ThreadLocalObject &obj = GetTLS(omp_get_thread_num());
      for (int i = 0; i < N; ++i) {
        #pragma omp for schedule(static)
        for (int j = first(i); j < last(i); ++j) {
          // Do some work with the help of obj
        }
      }
    }
    
    #pragma omp并行
    {
    ThreadLocalObject&obj=GetTLS(omp_get_thread_num());
    对于(int i=0;i
    我真的不明白为什么当您可以简单地使用。基本思路应遵循以下几点:

    #pragma omp parallel
    {      
      // Will hold an handle to the object pool
      auto pool = shared_ptr<ObjectPool>(nullptr); 
      #pragma omp single copyprivate(pool)
      {
        // A single thread creates a pool of num_threads objects
        // Copyprivate broadcasts the handle
        pool = create_object_pool(omp_get_num_threads());
      }
      for (int i = 0; i < N; ++i) 
      {
        #pragma omp parallel for schedule(static)
        for (int j = first(i); j < last(i); ++j) 
        {
            // The object is not re-created, just a reference to it
            // is returned from the pool
            auto & r = pool.get( omp_get_thread_num() );
            // Do work with r
        }
      }
    }
    
    #pragma omp并行
    {      
    //将保留对象池的句柄
    自动池=shared_ptr(nullptr);
    #pragma omp单副本专用(池)
    {
    //单个线程创建一个num_线程对象池
    //Copyprivate广播句柄
    pool=create_object_pool(omp_get_num_threads());
    }
    对于(int i=0;i
    @HighPerformanceMark,抛开打字错误不谈,我认为OPs问题很有趣,这在OpenMP问题中是很少见的。您对我使用
    threadprivate
    的解决方案有何评论?我犯了一个错误(我现在只使用C,我的C++是超级生锈的)?你的方法很好。您能告诉我为什么需要一个初始化为线程号的线程本地对象吗?