gpt4 book ai didi

c++ - 确定 OpenMP 原子指令的实现方式

转载 作者:太空狗 更新时间:2023-10-29 23:07:04 27 4
gpt4 key购买 nike

实现 OpenMP 标准的编译器可以(但没有义务)利用特殊的硬件指令在 #pragma omp atomic 指令原子之后进行某些内存更新,从而避免昂贵的锁。根据http://gcc.gnu.org/onlinedocs/gccint/OpenMP.html , GCC 实现原子更新如下:

Whenever possible, an atomic update built-in is used. If that fails, a compare-and-swap loop is attempted. If that also fails, a regular critical section around the expression is used.

  1. 如何确定在给定机器和 GCC 版本上实际使用的是这三者中的哪一个?是否有一些 GCC 的冗长选项,我可以设置它来查找而无需分析我的程序或查看生成的字节码?

  2. 是否有一些文档列出了提供原子加法/增量等指令的 CPU/架构,使我能够预测给定机器的结果?

我在各种不同的机器上使用 GCC 4.2 到 4.6 版。

最佳答案

您可以使用 -fdump-tree-all 选项查看中间树表示。鉴于该选项,GCC 在几个中间步骤中写入一组文件,并且可以观察应用于树的连续转换。 .ompexp 文件在这里特别重要,因为它包含在 OpenMP 表达式被扩展到它们的具体实现之后的树。

例如下面简单代码中parallel区域内的 block :

int main (void)
{
int i = 0;

#pragma omp parallel
{
#pragma omp atomic
i++;
}

return i;
}

在64位Linux上被GCC 4.7.2转化为:

;; Function main._omp_fn.0 (main._omp_fn.0, funcdef_no=1, decl_uid=1712, cgraph_uid=1)

main._omp_fn.0 (struct .omp_data_s.0 * .omp_data_i)
{
int D.1726;
int D.1725;
int i [value-expr: *.omp_data_i->i];
int * D.1723;
int * D.1722;

<bb 2>:
D.1722_2 = .omp_data_i_1(D)->i;
D.1723_3 = &*D.1722_2;
__atomic_fetch_add_4 (D.1723_3, 1, 0);
return;

}

最后变成:

00000000004006af <main._omp_fn.0>:
4006af: 55 push %rbp
4006b0: 48 89 e5 mov %rsp,%rbp
4006b3: 48 89 7d f8 mov %rdi,-0x8(%rbp)
4006b7: 48 8b 45 f8 mov -0x8(%rbp),%rax
4006bb: 48 8b 00 mov (%rax),%rax
4006be: f0 83 00 01 lock addl $0x1,(%rax)
4006c2: 5d pop %rbp
4006c3: c3 retq

至于第二个问题,可能还取决于GCC是如何构建的。

关于c++ - 确定 OpenMP 原子指令的实现方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13761851/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com