สรุป:
ดูเหมือนจะไม่มีวิธีรับประกันในการป้องกันการเรียงลำดับใหม่ แต่ตราบใดที่ไม่ได้เปิดใช้งานการเพิ่มประสิทธิภาพลิงก์เวลา / โปรแกรมเต็มการค้นหาฟังก์ชันที่เรียกว่าในหน่วยคอมไพล์แยกต่างหากดูเหมือนจะเป็นการเดิมพันที่ดีทีเดียวทีเดียว (อย่างน้อยกับ GCC แม้ว่าตรรกะจะแนะนำว่าสิ่งนี้มีแนวโน้มที่จะเกิดขึ้นกับคอมไพเลอร์อื่น ๆ ด้วย) สิ่งนี้มาพร้อมกับค่าใช้จ่ายของการเรียกใช้ฟังก์ชัน - โค้ดแบบอินไลน์เป็นไปตามคำจำกัดความในหน่วยคอมไพล์เดียวกันและเปิดให้จัดลำดับใหม่
คำตอบเดิม:
GCC จัดลำดับการโทรใหม่ภายใต้การเพิ่มประสิทธิภาพ -O2:
#include <chrono>
static int foo(int x) // 'static' or not here doesn't affect ordering.
{
return x*2;
}
int fred(int x)
{
auto t1 = std::chrono::high_resolution_clock::now();
int y = foo(x);
auto t2 = std::chrono::high_resolution_clock::now();
return y;
}
GCC 5.3.0:
g++ -S --std=c++11 -O0 fred.cpp
:
_ZL3fooi:
pushq %rbp
movq %rsp, %rbp
movl %ecx, 16(%rbp)
movl 16(%rbp), %eax
addl %eax, %eax
popq %rbp
ret
_Z4fredi:
pushq %rbp
movq %rsp, %rbp
subq $64, %rsp
movl %ecx, 16(%rbp)
call _ZNSt6chrono3_V212system_clock3nowEv
movq %rax, -16(%rbp)
movl 16(%rbp), %ecx
call _ZL3fooi
movl %eax, -4(%rbp)
call _ZNSt6chrono3_V212system_clock3nowEv
movq %rax, -32(%rbp)
movl -4(%rbp), %eax
addq $64, %rsp
popq %rbp
ret
แต่:
g++ -S --std=c++11 -O2 fred.cpp
:
_Z4fredi:
pushq %rbx
subq $32, %rsp
movl %ecx, %ebx
call _ZNSt6chrono3_V212system_clock3nowEv
call _ZNSt6chrono3_V212system_clock3nowEv
leal (%rbx,%rbx), %eax
addq $32, %rsp
popq %rbx
ret
ตอนนี้ด้วย foo () เป็นฟังก์ชันภายนอก:
#include <chrono>
int foo(int x);
int fred(int x)
{
auto t1 = std::chrono::high_resolution_clock::now();
int y = foo(x);
auto t2 = std::chrono::high_resolution_clock::now();
return y;
}
g++ -S --std=c++11 -O2 fred.cpp
:
_Z4fredi:
pushq %rbx
subq $32, %rsp
movl %ecx, %ebx
call _ZNSt6chrono3_V212system_clock3nowEv
movl %ebx, %ecx
call _Z3fooi
movl %eax, %ebx
call _ZNSt6chrono3_V212system_clock3nowEv
movl %ebx, %eax
addq $32, %rsp
popq %rbx
ret
แต่ถ้าสิ่งนี้เชื่อมโยงกับ -flto (การเพิ่มประสิทธิภาพเวลาเชื่อมโยง):
0000000100401710 <main>:
100401710: 53 push %rbx
100401711: 48 83 ec 20 sub $0x20,%rsp
100401715: 89 cb mov %ecx,%ebx
100401717: e8 e4 ff ff ff callq 100401700 <__main>
10040171c: e8 bf f9 ff ff callq 1004010e0 <_ZNSt6chrono3_V212system_clock3nowEv>
100401721: e8 ba f9 ff ff callq 1004010e0 <_ZNSt6chrono3_V212system_clock3nowEv>
100401726: 8d 04 1b lea (%rbx,%rbx,1),%eax
100401729: 48 83 c4 20 add $0x20,%rsp
10040172d: 5b pop %rbx
10040172e: c3 retq