目前我正在做一个项目,我想提高执行速度。我对并行编码完全陌生。我的程序最初有六个循环,我管理将其优化为三个循环,执行时间减少 300%。从我所研究的内容我认为问题出在索引上。我在之前的循环中已经使用了parfor,但索引是i = 1:vs_max-1。
在下面的代码中:
for i = 1:vs_max-1
for j = i+1:vs_max-1
d = max(abs(X(i,:)-X(j,:)));
DD = exp(-(d/r)^n);
D(i,j) = DD;
D(j,i) = DD;
while (i~=vs_max)
d2 = max(abs(X2(i,:)-X2(j,:)));
DD2 = exp(-(d2/r)^n);
D2(i,j) = DD2;
D2(j,i) = DD2;
break;
end
end
end
我相信问题出在第二个循环索引中,其中 j 也需要 i 值当我们有多个线程时,我们可以多次访问这些值。
谁能帮我重新索引这个循环,以便parfor不提示或提供其他类型的代码优化,以使上面的代码变得更快?
提前感谢您的善意阅读和回答我的帖子。
你基本上是在上三角矩阵中生成索引。随着i
值向vs_max-1
发展,线条越来越短。这不能很好地分布在多个线程之间,除非正在执行一些动态工作调度(例如,如果您碰巧熟悉 OpenMP,则类似于 schedule(dynamic)
)。
您可以"扁平化"事物并运行单个循环,并使用一些数学运算将迭代次数转换为(i,j)
对,例如,请参阅此问题以获取可能的解决方案。如果有足够的内存,还可以使用预填充的所有可能的(i,j)
对的列表,然后使用它快速计算迭代编号i
和j
。
顺便说一句:计算的第二部分看起来很奇怪。为什么要把它放在一个总是执行并且只执行一次的while
循环中(i ~= vs_max
总是正确的,因为i
永远不会达到vs_max
并且break
在第一次迭代后终止它)?