【发布时间】:2014-11-25 15:55:30
【问题描述】:
我正在尝试用 c++ (vs2010) 编写一段代码,它将使用 openMP 在并行模式下运行。一切运行完美(我的所有处理器都很忙,for 循环进度符合预期,但是当我达到时间步 i = 211 时,一切都变慢了。在进程监视器中,我看到我只使用了 14%),然后过了一会儿它再次加速,但在时间步上再次减慢i = 316。它会定期执行此操作,直到完成。我不确定发生了什么。由于我是新手,如果我的问题不够清楚,请原谅我。
这是代码:
xyQadrant 是在代码前面创建的向量 - 它包含结构!
方法GetUx(..), GetUY(..), CalcVelocity(...), CalcDisplacement(..) 在访问数据时使用锁定和解锁,因此多个线程对同一数据的多次访问应该不会有任何问题。
for(int i = 0; i < 1250; i++)
{
#pragma omp parallel num_threads(numCPU) shared(xyQuadrant)
{
#pragma omp for
for(int j = 0; j < xyQuadrant.size(); j++)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
for(int k = 0; k < xyQuadrant[j].qPoints.size(); k++)
{
point* targetPoint = &xyQuadrant[j].qPoints[k];
double strainX = 0;
double strainY = 0;
for (int n = 0; n < targetPoint->family.size(); n++)
{
point* curPoint = targetPoint->family[n];
if(fabs(curPoint->x - targetPoint->x) < 0.000001)
{
strainX = 0;
}
else
{
double directionX = (curPoint->GetUX(i-1) - targetPoint->GetUX(i-1) + curPoint->x - targetPoint->x)/fabs((curPoint->GetUX(i-1) - targetPoint->GetUX(i-1) + curPoint->x - targetPoint->x));
double stretchX = fabs((curPoint->GetUX(i-1) - targetPoint->GetUX(i-1) + curPoint->x - targetPoint->x - fabs((curPoint->x - targetPoint->x))))/fabs(curPoint->x - targetPoint->x);
strainX += directionX*c*stretchX*targetPoint->volumeCorrect[n]*(targetPoint->surfaceCorrectX + curPoint->surfaceCorrectX)/2;
}
if(fabs(curPoint->y - targetPoint->y) < 0.000001)
{
strainY = 0;
}
else
{
double directionY = (curPoint->GetUY(i-1) - targetPoint->GetUY(i-1) + curPoint->y - targetPoint->y)/fabs((curPoint->GetUY(i-1) - targetPoint->GetUY(i-1) + curPoint->y - targetPoint->y));
double stretchY = fabs((curPoint->GetUY(i-1) - targetPoint->GetUY(i-1) + curPoint->y - targetPoint->y - fabs((curPoint->y - targetPoint->y))))/fabs(curPoint->y - targetPoint->y);
strainY += directionY*c*stretchY*targetPoint->volumeCorrect[n]*(targetPoint->surfaceCorrectY+curPoint->surfaceCorrectY)/2;
}
}
targetPoint->aX = strainX*deltaV/density;
targetPoint->aY = strainY*deltaV/density;
targetPoint->CalcVelocity(deltaT);
targetPoint->CalcDisplacement(deltaT,i-1);
}
}
}
}
最后一点:我使用 i7-3770 处理器(4 个 proc 8 个线程)- 当一切都变慢时,我只能看到 4 个线程在工作,而其他 4 个线程显示 CPU 已停放!
【问题讨论】:
-
什么是
xyQuadrant.size()?它有多大?还可以尝试设置线程亲和性,以避免操作系统的核心停放计划。 -
xyQadrant 是一个结构向量,其中每个结构都包含属于它的点向量。 xyQuadrant 有 7140 个成员,每个 qPoints 向量有 cca 36 个成员!
-
好吧,它足够大,可以忘记负载平衡。线程亲和性建议仍然存在。如果您看到冻结与特定
i值的相关性,请检查取决于i的代码,即CalcDisplacement和 GetUX/UY -
我不确定如何在 Visual Studio 中设置线程亲和性!!一些帮助将不胜感激!
-
通读this question 并从那里选择一个工具。
标签: c++ multithreading loops for-loop openmp