velocity * timestep); -6ren">
gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 03:35:35 26 4
gpt4 key购买 nike

所以我有一些 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com