c++ - OpenMP 中的独立循环崩溃
问题描述
我有一个嵌套循环,如下所示 -
for(int i=0; i<limit1; i++)
{
for(int j=0; j<limit2; j++){
/*
Code with Custom function calls, branching etc etc.
*/
}
}
内循环和外循环迭代相互独立。由于这个循环不能简单地向量化,我想将它折叠到一个巨大的迭代空间中,以便可以更有效地展开它,从某种意义上说,不是只展开内部循环,而是可以展开组合的迭代空间。
我不想并行化它。根据我的理解,我不认为 openmp 提供了一个独立的 collapsing pragma like - #pragma omp collapse(2)
,而是将 collapse 子句与其他 pragma (如simd
or )结合使用for
。
可以通过 OpenMP 或其他方法来实现这一点。
PS - 我不确定这种方法的优缺点,是否会显着提高性能等等。如果有人解释理论上(即在基准测试之前)如何(或就此而言)确定这一点, 那会很好。
TIA
解决方案
首先,OpenMP 是“一种可在不同供应商的体系结构之间移植的并行编程模型”(来源: OpenMP 5.1 规范)。因此,如果您不想并行化循环,那么它可能不是正确的工具。
但是,请注意 OpenMP 提供了unroll
完全或部分展开循环嵌套的最外层循环的指令。完全展开循环的full
子句要求迭代计数(例如limit1
)是编译时常量(否则理论上是不可能的)。该partial
子句可以通过整数参数化,以控制展开多少次迭代。截至目前,GCC、ICC 和 Clang 都不支持这两个子句。
还有一个tile
指令可以重新排序两个嵌套循环的迭代,以便获得 2D 固定大小的图块。它没有向编译器指定应该展开循环。然而,一个积极优化的编译器可能会展开固定大小的循环嵌套,如果它不包含许多分支或函数调用(因为它通常不利于性能)。该指令不能与unroll
(因为 tile 循环没有规范的循环嵌套形式)结合使用。
请注意,如果迭代计数不是compile-time constants并且通常不是 if limit2
is not a power of two ,那么折叠(手动或使用工具自动)两个嵌套循环肯定不会帮助编译器。实际上,在这种情况下,肯定需要通过变量使用慢速模数或相当慢的无分支条件移动。对于编译器来说,展开这样的循环将非常困难(如果可能的话)。
推荐阅读
- javascript - 使用 AES 密钥 WebCrypto 解包 RSA 密钥
- python - 意外结果 Python:np.power(a,3)
- python - 为什么 PyCharm 抱怨 `Expected type 'Tag', got 'str' instead`?
- r - 闪亮的问题:图表不显示何时更新输入(加上一些错误)
- sql - 在 pl/sql 中将数据从游标添加到表时出现“不允许列”错误
- python - 无法生成 Azure CustomerProvidedEncryptionKey (cpk)
- multithreading - 如何加快 NumPy 中大量小协方差的计算?
- python - Python 替代 Java DataFlow 流代码
- swift - SwiftUI:从核心数据中获取一个洗牌的数组
- python - 用 bs4 解析价格