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;