Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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++ 为什么constexpr的性能比普通表达式差?_C++_C++11_Constexpr - Fatal编程技术网

C++ 为什么constexpr的性能比普通表达式差?

C++ 为什么constexpr的性能比普通表达式差?,c++,c++11,constexpr,C++,C++11,Constexpr,我知道在这方面也有类似的问题:。 但我的情况比那个简单得多,答案对我来说还不够。 我刚刚学习了C++11中的constexpr,a编写了一个代码来比较它的效率,出于某种原因,使用constexpr使我的代码运行速度慢了4倍多 顺便说一下,我使用的示例与本站点中的示例完全相同:(它是葡萄牙语的,但您可以看到有关constexpr的示例代码)。已经尝试过其他表达式,结果类似。 constexpr double divideC(double num){ return (2.0 * num +

我知道在这方面也有类似的问题:。
但我的情况比那个简单得多,答案对我来说还不够。 我刚刚学习了C++11中的constexpr,a编写了一个代码来比较它的效率,出于某种原因,使用constexpr使我的代码运行速度慢了4倍多
顺便说一下,我使用的示例与本站点中的示例完全相同:(它是葡萄牙语的,但您可以看到有关constexpr的示例代码)。已经尝试过其他表达式,结果类似。

constexpr double divideC(double num){
    return (2.0 * num + 10.0) / 0.8;
}

#define SIZE 1000
int main(int argc, char const *argv[])
{
    // Get number of iterations from user
    unsigned long long count;
    cin >> count;
    
    double values[SIZE];

    // Testing normal expression
    clock_t time1 = clock();
    for (int i = 0; i < count; i++)
    {
        values[i%SIZE] = (2.0 * 3.0 + 10.0) / 0.8;
    }
    time1 = clock() - time1;
    cout << "Time1: " << float(time1)/float(CLOCKS_PER_SEC) << " seconds" << endl;
    
    // Testing constexpr
    clock_t time2 = clock();
    for (int i = 0; i < count; i++)
    {
        values[i%SIZE] = divideC( 3.0 );
    }
    time2 = clock() - time2;
    cout << "Time2: " << float(time2)/float(CLOCKS_PER_SEC) << " seconds" << endl;

    return 0;
}
有人能告诉我原因吗?由于constexpr计算应该在编译时运行,因此应该更快而不是更慢地运行此代码

我正在使用msbuild版本16.6.0.22303编译由以下CMake代码生成的Visual Studio项目:

cmake_minimum_required(VERSION 3.1.3)
project(C++11Tests)

add_executable(Cpp11Tests main.cpp)

set_property(TARGET Cpp11Tests PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET Cpp11Tests PROPERTY CXX_STANDARD 11)

如果没有优化,编译器将保留
divideC
调用,因此速度较慢

通过对任何优秀的编译器进行优化,编译器都知道,对于给定的代码,与
值相关的所有内容都可以优化,而不会产生任何副作用。因此,所示代码永远无法给出
值[i%SIZE]=(2.0*3.0+10.0)/0.8之间的差异的任何有意义的测量
值[i%大小]=divideC(3.0)

使用
-O1
任何合适的编译器都会创建以下内容:

    for (int i = 0; i < count; i++)
    {
        values[i%SIZE] = (2.0 * 3.0 + 10.0) / 0.8;
    }

因此,这两种方法都会产生相同的机器代码,只包含循环计数,而不包含其他内容。因此,一旦启用优化,您将只测量循环,而与
constexpr
无关

使用
-O2
时,即使循环已优化,您也只需测量:

    clock_t time1 = clock();
    time1 = clock() - time1;
    cout << "Time1: " << float(time1)/float(CLOCKS_PER_SEC) << " seconds" << endl;
clock_t time1=clock();
time1=时钟()-time1;

你不能在启用优化的情况下编译吗?是的,请确定编译器、版本、标准选项和完整的编译/链接命令行……不,仅仅“Visual Studio编译器”远远不够。没有证据表明你在启用优化的情况下编译,如果你没有,性能度量没有任何意义。如果没有优化,编译器将保留
divideC
调用,因此速度较慢。通过对编译器进行优化,编译器知道与
值相关的所有内容都可以在没有任何副作用的情况下进行优化。因此,所示代码永远无法给出
值[i%SIZE]=(2.0*3.0+10.0)/0.8之间的差异的任何有意义的测量
值[i%大小]=divideC(3.0)
        mov     rdx, QWORD PTR [rsp+8]
        test    rdx, rdx
        je      .L2
        mov     eax, 0
.L3:
        add     eax, 1
        cmp     edx, eax
        jne     .L3
.L2:
    for (int i = 0; i < count; i++)
    {
        values[i%SIZE] = divideC( 3.0 );
    }
        mov     rdx, QWORD PTR [rsp+8]
        test    rdx, rdx
        je      .L4
        mov     eax, 0
.L5:
        add     eax, 1
        cmp     edx, eax
        jne     .L5
.L4:
    clock_t time1 = clock();
    time1 = clock() - time1;
    cout << "Time1: " << float(time1)/float(CLOCKS_PER_SEC) << " seconds" << endl;