Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ FMA性能与原始计算的比较_C++_Fma - Fatal编程技术网

C++ FMA性能与原始计算的比较

C++ FMA性能与原始计算的比较,c++,fma,C++,Fma,我试图比较FMA性能(math.h中的FMA())与浮点计算中的简单乘法和加法。测试很简单。对于大的迭代次数,我将重复相同的计算。为了进行精确的检查,我必须做到两件事 计数时间中不应包括其他计算 简单的乘法和加法不应优化为FMA 迭代不应该被优化。i、 迭代应该完全按照我的预期进行 为了实现上述目标,我做了以下工作: 函数是内联的,只包含所需的计算 使用g++-O0选项不优化乘法。(但当我查看转储文件时,它似乎为两者生成了几乎相同的代码) 已使用易失性 但结果显示,与简单的乘法和加法相比,几乎没

我试图比较FMA性能(
math.h
中的
FMA()
)与浮点计算中的简单乘法和加法。测试很简单。对于大的迭代次数,我将重复相同的计算。为了进行精确的检查,我必须做到两件事

  • 计数时间中不应包括其他计算
  • 简单的乘法和加法不应优化为FMA
  • 迭代不应该被优化。i、 迭代应该完全按照我的预期进行
  • 为了实现上述目标,我做了以下工作:

  • 函数是内联的,只包含所需的计算
  • 使用g++
    -O0
    选项不优化乘法。(但当我查看转储文件时,它似乎为两者生成了几乎相同的代码)
  • 已使用
    易失性
  • 但结果显示,与简单的乘法和加法相比,几乎没有差别,甚至更慢这是我想要的结果(即,它们在速度方面没有真正的不同),还是我做错了什么?

    规格

    • Ubuntu 14.04.2
    • G++4.8.2
    • 英特尔(R)核心(TM)i7-4770(3.4GHz,8MB三级缓存)
    我的代码

    #include <iostream>
    #include <cmath>
    #include <cstdlib>
    #include <chrono>
    using namespace std;
    using namespace chrono;
    
    inline double rand_gen() {
        return static_cast<double>(rand()) / RAND_MAX;
    }
    
    volatile double a, b, c;
    inline void pure_fma_func() {
        fma(a, b, c);
    }
    inline void non_fma_func() {
        a * b + c;
    }
    
    
    int main() {
        int n = 100000000;
    
        a = rand_gen();
        b = rand_gen();
        c = rand_gen();
    
        auto t1 = system_clock::now();
        for (int i = 0; i < n; i++) {
            non_fma_func();
        }
        auto t2 = system_clock::now();
        for (int i = 0; i < n; i++) {
            pure_fma_func();
        }
        auto t3 = system_clock::now();
    
        cout << "non fma" << endl;
        cout << duration_cast<microseconds>(t2 - t1).count() / 1000.0 << "ms" << endl;
        cout << "fma" << endl;
        cout << duration_cast<microseconds>(t3 - t2).count() / 1000.0 << "ms" << endl;
    }
    
    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    使用名称空间计时;
    内联双随机数发生器(){
    返回static_cast(rand())/rand_MAX;
    }
    挥发性双组分a、b、c;
    内联void pure_fma_func(){
    fma(a、b、c);
    }
    内联无效非函数(){
    a*b+c;
    }
    int main(){
    整数n=100000000;
    a=兰德·根();
    b=兰特·根();
    c=兰德·根();
    自动t1=系统时钟::现在();
    对于(int i=0;i是的,你做了一些完全错误的事情。至少有两件事。但让我们保持简单

    Used g++ -O0 option not to optimize the multiplication
    
    有趣的事实是:在这两种情况下,函数调用的成本都可能高于计算的成本

    从根本上说,没有启用优化的基准测试的结果是完全没有意义的。你不能仅仅关闭它们,然后期待最好的结果。它们绝对必须启用

    其次,FMA与常规乘法和加法的比较是一个复杂的情况——在延迟与吞吐量等问题上,乘法和加法可以成为赢家

    简而言之,您的基准根本不是基准,它只是一堆随机指令,它们产生了无意义的垃圾


    如果你想要一个准确的基准测试,你必须准确地再现实际的使用环境-完全。包括周围的代码,编译器优化,整个过程。

    是的,你做了一些完全错误的事情。至少有两件事。但让我们保持简单

    Used g++ -O0 option not to optimize the multiplication
    
    有趣的事实是:在这两种情况下,函数调用的成本都可能高于计算的成本

    从根本上说,没有启用优化的基准测试的结果是完全没有意义的。你不能仅仅关闭它们,然后期待最好的结果。它们绝对必须启用

    其次,FMA与常规乘法和加法的比较是一个复杂的情况——在延迟与吞吐量等问题上,乘法和加法可以成为赢家

    简而言之,您的基准根本不是基准,它只是一堆随机指令,它们产生了无意义的垃圾


    如果你想要一个准确的基准测试,你必须完全准确地再现实际的使用环境。包括周围的代码,编译器优化,整个系统。

    我用:
    g++test.cpp-mfma-O0-o test编译,结果显示两者都大约250ms。带
    -O0
    的基准测试毫无价值使用
    -O0
    -O2
    -O3
    从rom
    -O0
    中删除多少垃圾。尤其是跳转、加载和存储,这可能会很昂贵。您的测试有点臃肿。我使用以下工具编译:
    g++test.cpp-mfma-O0-o test
    ,结果显示这两个工具都大约250ms。使用
    -O0
    的基准测试毫无价值。比较一下用
    -O2
    -O3
    -O0
    中删除,然后查看删除了多少垃圾。尤其是跳跃、加载和存储,这可能会很昂贵。您的测试有点臃肿。