AMD CPU 和 Intel CPU 上的浮动算术差异

Difference of floating arithmetics on AMD CPUs and Intel CPUs

提问人:Singyuk Lau 提问时间:9/6/2023 最后编辑:phuclvSingyuk Lau 更新时间:9/6/2023 访问量:110

问:

我是计算科学专业的学生。当我在 AMD CPU 上处理混合精度项目时,我发现单精度数据的行为与双精度数据类似。有时,单精度数据比双精度数据花费更多的计算时间。但 Intel CPU 上的混合精度计算按预期执行。

一个简化的例子:

    double a = 1.0/3.0, c = 5.0/7.0;
    float b = 1.0/3.0, d = 5.0/7.0;
    double time4d = omp_get_wtime();
    for(int i = 0;i < 10000000;i ++)
    {
      a = a + c;
    }
    std::cout << omp_get_wtime() - time4d << std::endl;
    double time4f = omp_get_wtime();
    for(int i = 0;i < 10000000;i ++)
    {
      b = float(b) + float(d);
    }

    std::cout << omp_get_wtime() - time4f << std::endl;

我正在使用带有以下标志的 g++:

-o main -fopenmp -O0 -ffloat-store

在配备 AMD EPYC 7713 64 核处理器的服务器上,输出为:

0.0388171
0.0388219

但是,在配备 Intel(R) Xeon(R) Gold 6136 CPU 的服务器上,输出为:

0.0424005
0.0244199

我想知道我是否错过了一些标志或操作,使单精度无法像预期的那样在 AMD CPU 上运行。是什么导致了这种现象?此外,如何使混合精度计算在 AMD CPU 上工作?

C++ 浮点 x86-64 AMD 处理器

评论

11赞 njuffa 9/6/2023
-O0 -ffloat-store基本上会导致未优化的,甚至是“悲观”的构建,对吗?恕我直言,对未优化的代码进行基准测试是没有意义的。你想完成什么?
7赞 njuffa 9/6/2023
[1] 使用完整的优化进行编译,例如,但对 IEEE-754 具有相对较高的保真度,例如,并避免“快速和肮脏”的优化,例如为每个目标体系结构添加优化标志。[2] 分析生成的汇编代码。[3] 配置文件代码,提取突出的 CPU 事件计数器 [4] 设置从步骤 (1) 到 (3) 中瞥见的与 CPU 架构详细信息相关的内容。您在此处发布的基准测试就是所谓的综合测试。这些在很大程度上是没有意义的,而是在库函数或应用程序级别进行基准测试。-O3-fp-model=precise-ffast-math
3赞 Peter Cordes 9/6/2023
有关 Intel/AMD 微架构的差异,请参阅 agner.org/optimize,特别是他的 microarch PDF。还有 uops.info。有了它,以及你测试的编译器生成的 asm,你可以看到可能存在哪些瓶颈。(另外,在现代超标量处理器上预测操作的延迟时需要考虑哪些因素?
3赞 Peter Cordes 9/6/2023
正如 njuffa 所说,如果你想知道正常的高效代码将如何运行,那么基准测试代码是没有意义的;为什么 clang 在 -O0 上会产生低效的 asm?,但如果你想知道为什么该可执行文件在不同的 CPU 上以不同的速度运行,可以通过仔细查看编译器生成的 asm(而不是源代码)来发现一个原因。不过,这可能与优化代码的正常情况无关。-O0
3赞 Jesper Juhl 9/6/2023
没有一个头脑正常的人会在生产中发布未优化的代码。未优化的代码 () 的存在是为了通过使调试器在单步执行源代码时产生预期的结果来帮助调试 - 但性能(通常)很糟糕。C++ 在很大程度上依赖于编译器优化来删除抽象,并以其他方式提高所编写代码的性能。对于任何现实生活/生产代码,任何称职的程序员都会使用类似 or 的东西(通常也 )来构建他们的代码,这就是您应该测试的性能。-O0-O2-O3-flto

答: 暂无答案