我正在尝试重写此外部for
循环,以允许多个线程并行执行迭代。实际上,尽管更通用的解决方案是理想的,但现在我只希望两个线程来计算此值。问题在于存在循环依赖:将nval[j]
的先前值与nval[j]
的此迭代值一起添加到avval
的先前值。
void loop_func(Arr* a, int blen, double* nval) {
// an Arr is a struct of an array and len field
assert(a->len < blen);
long long int i = 0, j = 0, jlo = 0, jhi = 0;
double avval = 0.0;
for (i = 0; i < blen; i++)
nval[i] = 0.0;
const double quot = static_cast<double>(blen) / static_cast<double>(a->len);
for (auto i = 1; i < a->len - 1; i++) {
j_lower = (int)(0.5 * (2 * i - 1) * quot);
j_upper = (int)(0.5 * (2 * i + 1) * quot);
printf("a->val index: %lld\t\tnval index: %lld-%lld\n", i, j_lower, j_upper);
avval = a->val[i] / (j_upper - j_lower + 1);
for (j = j_lower; j <= j_upper; j++) {
nval[j] += avval;
}
}
}
为方便起见,我将打印出一些通过上面的printf
打印的详细信息。
a->val index: 1 nval index: 1-3
a->val index: 2 nval index: 3-5
a->val index: 3 nval index: 5-7
a->val index: 4 nval index: 7-9
a->val index: 5 nval index: 9-11
a->val index: 6 nval index: 11-13
理想情况下,我希望线程1处理a-> val索引1-3,线程2处理a-val索引4-6。
问题1:任何人都可以描述将消除这种依赖性的代码转换吗?
问题2:?有C / C ++工具可以做到这一点吗?也许是用LLVM构建的?我可能会遇到许多类似的情况,这些情况下我需要执行一些并行执行。同样,如果可以应用一些通用技术来删除此类循环承载的依赖项,我想更广泛地了解这一点。