【问题标题】:Is it possible to parallelize or unroll this loop?是否可以并行化或展开此循环?
【发布时间】:2018-07-06 20:43:09
【问题描述】:

我正在尝试查看是否可以提高 C++ 中以下循环的性能,该循环使用二维向量(_external 和 _Table),并且对上一次迭代具有携带循环依赖性。此外,它在最内层循环中有一个计算索引访问器,这将使 _Table 在右侧的访问是非顺序的。

int N = 8000;
int M = 400
int P = 100;
for(int i = 1; i <= N; i++){
    for(int j = 0; j < M; j++){
        for(int k =0; k < P; k++){
            int index = _external.at(j).at(k);
            _Table.at(j).at(i) += _Table.at(index).at(i-1);
        }
    }
}

我可以做些什么来提高这样的循环的性能?

【问题讨论】:

    标签: multithreading performance for-loop parallel-processing


    【解决方案1】:

    在我看来,这些语句的顺序是这样的:

        int index = _external.at(j).at(k);
        _Table.at(j).at(i) += _Table.at(index).at(i-1);
    

    被执行对正确性至关重要。 (也就是说,如果i、j、k的迭代顺序发生变化,那么结果就会不同……而且不正确。)

    所以我认为你只剩下微优化了,比如将表达式 _Table.at(j).at(i)_external.at(j) 提升到最内层循环之外。

    考虑一下:

        for(int k =0; k < P; k++){
            int index = _external.at(j).at(k);
            _Table.at(j).at(i) += _Table.at(index).at(i-1);
        }
    

    此循环重复向_Table.at(j).at(i) 添加数字。由于(通过检查)_Table.at(index).at(i-1) 必须从表格的不同单元格读取(因为i-1i),您可以这样做:

        int temp = 0;
        for(int k =0; k < P; k++){
            int index = _external.at(j).at(k);
            temp += _Table.at(index).at(i-1);
        }
        _Table.at(j).at(i) += temp;
    

    这将减少对at 的调用次数,还可能会稍微提高缓存性能。

    【讨论】:

    • 谢谢 - 是的,我已经尝试过提升该临时变量。它在执行时间上并没有太大的区别。我刚刚发布了代码的“原始”版本,以确保我没有遗漏任何东西。我怀疑我将不得不回到绘图板上,看看我是否可以找到一种不同的方法来为我的算法获得正确的结果,而无需使用这种类型的循环。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 2020-09-16
    相关资源
    最近更新 更多