【发布时间】:2014-05-14 04:41:31
【问题描述】:
谁能解释一下这些表达式之间的这些相当大的性能差异,我希望这些差异具有相似的性能。我正在发布模式下使用 Apple LLVM 版本 5.1 (clang-503.0.38)(基于 LLVM 3.4svn)进行编译。
这是我的测试代码(只需将 CASE 更改为 1、2、3 或 4 来测试自己):
#include <iostream>
#include <chrono>
#define CASE 1
inline int foo(int n) {
return
#if CASE == 1
(n % 2) ? 9 : 6
#elif CASE == 2
(n % 2) == true ? 9 : 6
#elif CASE == 3
6 + (n % 2) * 3
#elif CASE == 4
6 + bool(n % 2) * 3
#endif
;
}
int main(int argc, const char* argv[])
{
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
int n = argc;
for (int i = 0; i < 100000000; ++i) {
n += foo(n);
}
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "elapsed time: " << elapsed_seconds.count() << "\n";
std::cout << "value: " << n << "\n";
return 0;
}
这是我得到的时间:
CASE EXPRESSION TIME
1 (n % 2) ? 9 : 6 0.1585
2 (n % 2) == true ? 9 : 6 0.3491
3 6 + (n % 2) * 3 0.2559
4 6 + bool(n % 2) * 3 0.1906
CASE 1 和 CASE 2 的组装区别如下:
案例 1:
Ltmp12:
LBB0_1: ## =>This Inner Loop Header: Depth=1
##DEBUG_VALUE: main:argv <- RSI
##DEBUG_VALUE: i <- 0
.loc 1 24 0 ## /Test/main.cpp:24:0
movl %ebx, %ecx
andl $1, %ecx
leal (%rcx,%rcx,2), %ecx
Ltmp13:
.loc 1 48 14 ## /Test/main.cpp:48:14
leal 6(%rbx,%rcx), %ebx
案例 2:
Ltmp12:
LBB0_1: ## =>This Inner Loop Header: Depth=1
##DEBUG_VALUE: main:argv <- RSI
##DEBUG_VALUE: i <- 0
.loc 1 24 0 ## /Test/main.cpp:24:0
movl %ebx, %ecx
shrl $31, %ecx
addl %ebx, %ecx
andl $-2, %ecx
movl %ebx, %edx
subl %ecx, %edx
cmpl $1, %edx
sete %cl
movzbl %cl, %ecx
leal (%rcx,%rcx,2), %ecx
Ltmp13:
.loc 1 48 14 ## /Test/main.cpp:48:14
leal 6(%rbx,%rcx), %ebx
这是 CASE 3 和 CASE 4 在组装上的区别:
案例 3:
Ltmp12:
LBB0_1: ## =>This Inner Loop Header: Depth=1
##DEBUG_VALUE: main:argv <- RSI
##DEBUG_VALUE: i <- 0
.loc 1 24 0 ## /Test/main.cpp:24:0
movl %ebx, %ecx
shrl $31, %ecx
addl %ebx, %ecx
andl $-2, %ecx
movl %ebx, %edx
subl %ecx, %edx
leal (%rdx,%rdx,2), %ecx
Ltmp13:
.loc 1 48 14 ## /Test/main.cpp:48:14
leal 6(%rbx,%rcx), %ebx
案例 4:
Ltmp12:
LBB0_1: ## =>This Inner Loop Header: Depth=1
##DEBUG_VALUE: main:argv <- RSI
##DEBUG_VALUE: i <- 0
.loc 1 24 0 ## /Test/main.cpp:24:0
movl %ebx, %ecx
andl $1, %ecx
negl %ecx
andl $3, %ecx
Ltmp13:
.loc 1 48 14 ## /Test/main.cpp:48:14
leal 6(%rbx,%rcx), %ebx
【问题讨论】:
-
你的编译标志是??在不知道应用了哪些优化的情况下,这是一个毫无意义的比较。到目前为止 - 不同数量的汇编指令给出不同的执行时间,这应该是显而易见的。
-
我使用的是 Xcode,所以我不容易看到所有的标志,但我能看到的一个重要标志是 -Os
-
-O2看起来像什么?否则,看起来优化器失败了。 -
对于 coliru (
-O3) 的 clang++ 和 g++,(n % 2) != false ? 9 : 6明显快于(n % 2) == true ? 9 : 6 -
@dyp 这很有趣!看起来像是优化器的极端案例。
标签: c++ performance clang performance-testing clang++