为什么constexpr的性能比正常表达式差
Why is constexpr performing worse than normal expression?
我知道还有一个类似的问题:constexpr在运行时表现更差
但我的案子比那个简单多了,而且答案对我来说还不够。我只是在C++11中学习constexpr,a编写了一段代码来比较它的效率,出于某种原因,使用constexpr会使我的代码运行速度慢4倍多
顺便说一句,我使用的示例与本网站中的示例完全相同:https://www.embarcados.com.br/introducao-ao-cpp11/(它是葡萄牙语,但你可以看到关于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;
}
给出的输入:9999999999
输出:
> Time1: 5.768 seconds
> Time2: 27.259 seconds
有人能告诉我原因吗?由于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
调用,因此速度较慢。
任何一个优秀的编译器都知道,对于给定的代码,与values
相关的一切都可以在没有任何副作用的情况下进行优化。因此,所示代码永远不能给出values[i%SIZE] = (2.0 * 3.0 + 10.0) / 0.8;
或values[i%SIZE] = divideC( 3.0 );
之间的任何有意义的测量
有了-O1
,任何优秀的编译器都会创建这样的东西:
for (int i = 0; i < count; i++)
{
values[i%SIZE] = (2.0 * 3.0 + 10.0) / 0.8;
}
结果在:
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:
因此,两者都将产生相同的机器代码,只包含循环的计数,而不包含其他内容。因此,一旦启用优化,您将只测量循环,而不测量与constexpr
相关的内容。
有了-O2
,即使循环也被优化掉了,你只能测量:
clock_t time1 = clock();
time1 = clock() - time1;
cout << "Time1: " << float(time1)/float(CLOCKS_PER_SEC) << " seconds" << endl;
相关文章:
- 为什么constexpr的性能比正常表达式差
- 在现代C++中,侵入式容器是否仍然比非侵入式容器具有性能优势?
- 每个编译器的C++性能,比C#慢200倍
- C++多线程性能比单线程代码慢
- 多线程功能性能比单线螺纹差
- localtime() 比 Linux 上的 gmtime() 性能问题多 24 倍
- 为什么 pcre 正则表达式比 c++11 正则表达式快得多
- 为什么这个普通的数组实现比STD ::向量实现性能慢
- C:pthread的性能,比单线程低
- 全局对象是否提供比多个本地实例更好的性能
- 为什么 std::make_shared<>() 的性能比 boost::make_shared() 好得多?
- 为什么预分配的函数指针的性能比分支差
- C++与.NET正则表达式性能
- 提升::正则表达式性能问题
- 放炮的性能比先放炮后复核的性能差
- 为什么我的散点代码的性能比Vc SIMD更好
- 为什么 C++ fseek/fread 的性能比 C# FileStream 的 Seek/Read 高几倍
- 对于指数,特征表达式模板比手动循环慢
- 使用Eigen的性能比使用我自己的类更差
- OpenMP C++并行性能比八核集群更好的双核笔记本电脑