c++ - 是否可以创建一个线程组,然后只有 "use"线程?

标签 c++ multithreading parallel-processing openmp

所以我有一些 OpenMP 代码:

for(unsigned int it = 0; it < its; ++it)
{
    #pragma omp parallel
    {
        /**
         * Run the position integrator, reset the
         * acceleration, update the acceleration, update the velocity.
         */

          #pragma omp for schedule(dynamic, blockSize)
          for(unsigned int i = 0; i < numBods; ++i)
          {
              Body* body = &bodies[i];
              body->position += (body->velocity * timestep);
              body->position += (0.5 * body->acceleration * timestep * timestep);

              /**
               * Update velocity for half-timestep, then reset the acceleration.
               */
              body->velocity += (0.5f) * body->acceleration * timestep;
              body->acceleration = Vector3();
          }

          /**
           * Calculate the acceleration.
           */
          #pragma omp for schedule(dynamic, blockSize)
          for(unsigned int i = 0; i < numBods; ++i)
          {
              for(unsigned int j = 0; j < numBods; ++j)
              {
                  if(j > i)
                  {
                      Body* body = &bodies[i];
                      Body* bodyJ = &bodies[j];

                    /**
                     * Calculating some of the subsections of the acceleration formula.
                     */
                    Vector3 rij = bodyJ->position - body->position;
                    double sqrDistWithEps = rij.SqrMagnitude() + epsilon2;
                    double oneOverDistCubed = 1.0 / sqrt(sqrDistWithEps * sqrDistWithEps * sqrDistWithEps);
                    double scalar = oneOverDistCubed * gravConst;

                    body->acceleration += bodyJ->mass * scalar * rij;
                    bodyJ->acceleration -= body->mass * scalar * rij; //Newton's Third Law.
                }
            }
        }

        /**
         * Velocity for the full timestep.
         */
        #pragma omp for schedule(dynamic, blockSize)
        for(unsigned int i = 0; i < numBods; ++i)
        {
            bodies[i].velocity += (0.5 * bodies[i].acceleration * timestep);
        }
    }

    /**
     * Don't want I/O to be parallel
     */
    for(unsigned int index = 1; index < bodies.size(); ++index)
    {
        outFile << bodies[index] << std::endl;
    }
}

这很好,但我忍不住认为在每次迭代中 fork 一组线程是个坏主意。但是,迭代必须按顺序进行;所以我不能让迭代本身是并行的。

我只是想知道是否有一种方法可以将其设置为在每次迭代中重用相同的线程组?

最佳答案

据我所知,这是最合乎逻辑的方法,线程池已经创建,每次线程到达并行构造函数时,它都会从池中请求一组线程。因此,它不会在每次到达并行区域构造函数时都创建一个线程池,但是如果您想重用相同的线程,为什么不直接将并行构造函数推出循环并使用 处理顺序代码单个 pragma,像这样:

#pragma omp parallel
{
    for(unsigned int it = 0; it < its; ++it)
    {
       ...

          ...

        /**
        * Don't want I/O to be parallel
        */

       #pragma omp single
       {
           for(unsigned int index = 1; index < bodies.size(); ++index)
           {
               outFile << bodies[index] << std::endl;
           }
       } // threads will wait in the internal barrier of the single 
   }
}

我进行了快速搜索,这个答案的第一段可能取决于您正在使用的 OpenMP 实现,我强烈建议您阅读您正在使用的那个的手册。

表格示例,来自source :

OpenMP* is strictly a fork/join threading model. In some OpenMP implementations, threads are created at the start of a parallel region and destroyed at the end of the parallel region. OpenMP applications typically have several parallel regions with intervening serial regions. Creating and destroying threads for each parallel region can result in significant system overhead, especially if a parallel region is inside a loop; therefore, the Intel OpenMP implementation uses thread pools. A pool of worker threads is created at the first parallel region. These threads exist for the duration of program execution. More threads may be added automatically if requested by the program. The threads are not destroyed until the last parallel region is executed.

不过,如果您将并行区域放在循环之外,您就不必担心上一段中提到的潜在开销。

关于c++ - 是否可以创建一个线程组,然后只有 "use"线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41187970/

相关文章:

c++ - GCC 编译的静态库包含什么?

c++ - 在多线程应用程序中,我将如何使用原子内置函数来设置/查看 time_t 值?

c# - Delegate.BeginInvoke 与 ThreadPool.QueueWorkerUserItem

r - R中的嵌套foreach循环,其中内部循环返回一个矩阵

c++ - signed int 需要多少位以及按位移位到作为其类型限制的数字左侧的行为

c++ - 如何将 Python 中的脚本转换为 C++?

asp.net-mvc - ASP.NET MVC和长时间运行的操作

c# - 运行具有连续值返回的多个线程(ping 程序)

java - 如何将 selenium webdriver 实例与 java 绑定(bind)并行化?

for-loop - 带有 return 语句的 Julia @parallel for 循环