【问题标题】:Transform a loop for parallelisation转换循环以进行并行化
【发布时间】:2020-02-29 09:28:05
【问题描述】:

我可以用这段代码做哪些其他循环转换来增加潜在的并行度?

代码在这里:

for (int i=10; i<N; i++)
{
    A[i] = B[i] * 14.3 / A[10];
    C[i] = C[i-1] + C[i-2];
}

到目前为止我所做的是使用循环剥离:

A[10] = B[10] * 14.3 /A[10]
C[10] = C[10-1] + C[10-2];
for(int i = 11 ; i<N; i++)
{
    A[i] = B[i] * 14.3 / A[10];
    C[i] = C[i-1] + C[i-2];
 }

这解决了第一行,但无论如何我可以在循环内转换第二行吗?

【问题讨论】:

  • A[i] = B[i] * 14.3 / A[10]; 与您的问题无关,因为其中没有依赖关系,也不会在另一行产生任何依赖关系。

标签: algorithm loops parallel-processing


【解决方案1】:
for (int i=10; i<N; i++)
    {
    A[i] = B[i] * 14.3 / A[10];
    C[i] = C[i-1] + C[i-2];
    }

所以A[10] 是您已经发现的特殊情况,C 不依赖于A,B 并使用浮点或定点(因此您可以使用预先计算的常数而不会造成很大的精度损失),因此您可以拆分进入:

// serial
A[10] = B[10] * 14.3 / A[10];
c0 = 14.3 / A[10];
// thread 1
for (int i=11; i<N; i++) A[i] = B[i] * c0;
// thread 2
for (int i=10; i<N; i++) C[i] = C[i-1] + C[i-2];

现在B 独立于A,因此您可以在任意数量的线程上并行执行第一个循环(最多 N-11)...

第二个循环依赖于先前的结果,因此除非知道更多关于 C 的知识和结果准确性,否则您不能拆分它。

导致:

// serial
A[10] = B[10] * 14.3 / A[10];
c0 = 14.3 / A[10];
for (i0=11,i1=11+(N-11)/M,j=1;j<=M;j++,i0=i1,i1=11+j*(N-11)/M)
 // threads 1...M 
 for (int i=i0; i<i1; i++) A[i] = B[i] * c0;
// thread M+1
for (int i=10; i<N; i++) C[i] = C[i-1] + C[i-2];

【讨论】:

    猜你喜欢
    • 2012-12-09
    • 2018-06-19
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2013-12-08
    相关资源
    最近更新 更多