了解 openmp 中的折叠子句

2023-12-20

我遇到了一个包含崩溃子句的 OpenMP 代码,这对我来说是新的。我试图理解它的含义,但我认为我还没有完全理解它的含义;我发现的一个定义是:

COLLAPSE https://computing.llnl.gov/tutorials/openMP/:指定嵌套循环中的多少个循环应折叠到一个大的迭代空间中,并根据schedule子句进行划分。所有关联循环中迭代的顺序执行决定了折叠迭代空间中迭代的顺序。

我以为我明白这意味着什么,所以我尝试了以下简单的程序:

int i, j;
#pragma omp parallel for num_threads(2) private(j)
for (i = 0; i < 4; i++)
    for (j = 0; j <= i; j++)
        printf("%d %d %d\n", i, j, omp_get_thread_num());

哪个生产的

0 0 0
1 0 0
1 1 0
2 0 0
2 1 0
2 2 1
3 0 1
3 1 1
3 2 1
3 3 1

然后我添加了collapse(2)条款。我预计前两列会得到相同的结果,但现在有相同数量的0's and 1在最后一列中。 但我得到了

0 0 0
1 0 0
2 0 1
3 0 1

所以我的问题是:

  1. 我的代码中发生了什么?
  2. 什么情况下我应该使用collapse?
  3. 您能否提供一个示例来说明使用之间的区别collapse并且不使用它?

您的代码的问题在于内部循环的迭代取决于外部循环。根据OpenMP规范下有关绑定部分的描述以及collapse clause:

如果任何关联循环的执行改变了用于计算任何值的任何值 迭代计数,则行为未指定。

当情况并非如此时,您可以使用折叠,例如使用方形循环

#pragma omp parallel for private(j) collapse(2)
for (i = 0; i < 4; i++)
    for (j = 0; j < 100; j++)

事实上,这是一个很好的例子来展示何时使用折叠。外循环只有四次迭代。如果你有四个以上的线程,那么有些线程就会被浪费。但是,当您折叠时,线程将分布在 400 次迭代中,这可能比线程数大得多。使用塌陷的另一个原因是载荷分布不均匀。如果您只使用了四次迭代,并且第四次迭代占用了其他线程等待的大部分时间。但如果使用 400 次迭代,负载可能会得到更好的分布。

您可以为上面的代码手动融合一个循环,如下所示

#pragma omp parallel for
for(int n=0; n<4*100; n++) {
    int i = n/100; int j=n%100;

Here https://stackoverflow.com/questions/18749493/openmp-drastically-slows-down-for-loop/18763554#18763554是一个示例,展示了如何手动熔合三重熔合环。

最后,here https://stackoverflow.com/questions/24013832/fusing-a-triangle-loop-for-parallelization-calculating-sub-indices是一个示例,显示如何融合三角形环collapse没有定义。


这是一个将 OP 问题中的矩形循环映射到三角形循环的解决方案。这可用于融合 OP 三角环。

//int n = 4;
for(int k=0; k<n*(n+1)/2; k++) {
    int i = k/(n+1), j = k%(n+1);
    if(j>i) i = n - i -1, j = n - j;
    printf("(%d,%d)\n", i,j);
}

这适用于任何 n 值。

OP问题的地图来自

(0,0),
(1,0), (1,1),
(2,0), (2,1), (2,2),
(3,0), (3,1), (3,2), (3,3),

to

(0,0), (3,3), (3,2), (3,1), (3,0),
(1,0), (1,1), (2,2), (2,1), (2,0),

对于 n 的奇数值,地图并不完全是矩形,但公式仍然有效。

例如 n = 3 映射自

(0,0),
(1,0), (1,1),
(2,0), (2,1), (2,2),

to

(0,0), (2,2), (2,1), (2,0),
(1,0), (1,1),

这是测试这个的代码

#include <stdio.h>
int main(void) {
    int n = 4;
    for(int i=0; i<n; i++) {
        for(int j=0; j<=i; j++) {
            printf("(%d,%d)\n", i,j);
        }
    }
    puts("");
    for(int k=0; k<n*(n+1)/2; k++) {
        int i = k/(n+1), j = k%(n+1);
        if(j>i) i = n - i - 1, j = n - j;
        printf("(%d,%d)\n", i,j);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 openmp 中的折叠子句 的相关文章

随机推荐

  • Drupal 8:如何自定义表单小部件以显示实体字段值而不是实体标题?

    我正在通过开发自定义表单小部件模块来迈出了解 Drupal 8 在幕后如何工作的第一步 我的目标是显示引用节点的图像字段值 而不是单选按钮列表中的节点标题 在核心中可用 这将允许网站管理员在为节点选择背景图像时选择图片而不是文本 以下是我的
  • 你能让div中的浮动元素不换行吗?

    目标浏览器为IE8 我有一个 div 其中包含向左浮动的元素列表 元素宽度可以在运行时改变 我想做的是 如果它们不再适合 div 它就会被切断并且不会换行 它似乎只有在该项目本身位于一行时才有效 此页面演示了该问题 文本输入的宽度需要在运行
  • VSCode“无法打开file.cs:找不到文件”

    我通过重命名文件夹或其他内容破坏了我的 vscode 项目 不完全确定发生了什么 问题是 虽然我仍然可以构建和运行没有问题 但有些东西已经搞砸了 因此当我收到编译错误时 例如当我双击它说的消息时 无法打开 XXXController cs
  • 更新 edittext 时会发生什么事件?

    我有一个 android 布局 其中有两个编辑文本 一个用于数量 一个用于费率 一个文本视图用于总量 现在我想做的是每当用户更改费率或数量字段时更改 更新总金额 我正在寻找的 edittext 事件是什么 我可以像设置 OnClick 一样
  • 如何分割这个字符串?

    我想分割这个字符串 String info 0 542008835 meters height from ground 由此我只想得到两位小数0 54 通过使用这个我得到了 String new rhs split lt G 但我在这里面临
  • 如何通过仅更改域名而保留其他 URL 参数来重定向 URL

    我现在正在将我的网站迁移到新的主机和域 我想知道是否可以将输入旧网站的任何 URL 的任何人重定向到新网站 同时保留所有 URL 参数 例如 当有人输入这个网址时http www domainA com blog p 667 我希望他被重定
  • 如何在 ruby​​ 中使用 AES 256 ECB PKCS5Padding 加密数据

    我想使用 PKCS5padding 以 AES 256 位 ECB 模式加密数据 我的ruby方法如下 这里如何使用PKCS5Padding def encrypt raw data key cipher OpenSSL Cipher AE
  • 更新行而不是创建新条目数据库android

    我一直在研究 Android 食谱书中的食谱 以利用数据库来存储事件 当前代码允许我添加新条目 但无法修改任何添加的条目 我需要的是一个具有预定义行数 48 的数据库 并且具有通过相应的编辑文本字段更新这些行的功能 任何人都可以帮我修改以下
  • Karma 和 React,有导致错误的警告

    我在用Karma http karma runner github io 0 8 index html with mocha http mochajs org 测试我的React https facebook github io react
  • .NET 日期时间到 SqlDateTime 转换

    在将 NET DateTime 默认情况下 DateTime 转换为 SqlDateTime 时 我应该始终检查 NET 日期是否在 SqlDateTime MinValue 和 SqlDateTime MaxValue 之间 或者 有没有
  • Ruby rspec 命令不起作用,可能是因为 Ubuntu 12 是 64 位吗?

    我在这个问题上曾经很头疼过 我目前正在做一项作业 要求我在 ruby 上使用 rspec 每当我运行 rspec 命令时 我都会收到类似错误 home rvm gems ruby 1 9 3 p286 gems rspec core 2 1
  • 如何替换 MySQL 中的正则表达式模式

    我有一张桌子叫myTable其中有一个名为col1 此列包含以下格式的数据 1 或 2 位数字 连字符 8 位数字 我想替换此列中的所有数据 并将连字符之前的所有内容替换为 4 所以这是一个示例 old values New Values
  • 在 64 位机器上很长[重复]

    这个问题在这里已经有答案了 64位机器上是long 128位吗 Edit 重复问题 看x64 上的 sizeof int https stackoverflow com questions 651956 sizeofint on x64 在
  • 在 bash 脚本中插入包含“$”的变量

    我正在编写一个创建用户帐户的 bash 脚本 用户名和密码哈希值是根据特定标准从文件中提取的 密码哈希自然包含分隔哈希字段的 例如 1 SALT 问题是 p 选项useradd需要用单引号将密码哈希括起来 以防止 字段作为变量进行插值 传递
  • 如何更改 Flutter Web 中的 chrome 标题颜色?

    顶部带有链接 URL 的标题的默认颜色是蓝色 有人知道如何更改它的颜色吗 将此元标记放在index html 文件中的 head 标记之间 它将更改您的移动浏览器的顶部菜单颜色
  • LeafletJS 标记随缩放而移动

    使用 LeafletJS 这是王牌 到目前为止 P 我们没有 JSON 对象或任何东西 所以我从 HTML 中取出值 标题 latlng 并创建标记 一般来说 这可以正常工作 但是它们的绘图存在问题 当地图真正放大时 它们似乎还不错 但当您
  • jquery:我怎么知道我是否拥有它?

    我需要 jquery 在本地浏览器上工作 我如何知道它是否已安装以及如何安装 我的问题是特定于能够运行此代码 onmouseover evt target setAttribute opacity 0 5 someDiv show onmo
  • 具有多个 https 站点的 HAproxy

    我们有几个在负载均衡器后面运行的 http 站点 使用hearbeat 具有故障转移功能 和一个 https 站点 一切都运行良好 但现在我想要 添加另一个 https 站点 我找不到任何托管多个 https 站点的参考资料 有人使用 HA
  • 在 pySpark 中使用 paramGrid 从 CrossValidator 中提取结果

    我用 pySpark 训练随机森林 我想要一个包含网格中每个点的结果的 csv 我的代码是 estimator RandomForestRegressor evaluator RegressionEvaluator paramGrid Pa
  • 了解 openmp 中的折叠子句

    我遇到了一个包含崩溃子句的 OpenMP 代码 这对我来说是新的 我试图理解它的含义 但我认为我还没有完全理解它的含义 我发现的一个定义是 COLLAPSE https computing llnl gov tutorials openMP