問題:爲什麼功能的性能不同,當我分別編譯和鏈接?爲什麼功能的性能不同,當我分別編譯和鏈接?
首先,在CODE
randoms.hpp
int XORShift();
int GameRand();
randoms.cpp
static unsigned int x = 123456789;
static unsigned int y = 362436069;
static unsigned int z = 521288629;
static unsigned int w = 88675123;
int XORShift()
{
unsigned int t = x^(x << 11);
x = y;
y = z;
z = w;
return w = w^(w >> 19)^(t^(t >> 8));
}
static unsigned int high = 0xDEADBEEF;
static unsigned int low = high^0x49616E42;
int GameRand()
{
high = (high << 16) + (high >> 16);
high += low;
low += high;
return high;
}
的main.cpp
#include <iostream>
#include <windows.h>
#include "randoms.hpp"
using namespace std;
//Windows specific performance tracking
long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart)/s_frequency.QuadPart;
}
void main() {
const int numCalls = 100000000; //100 mil
{
cout << "XORShift..." << endl;
long long start = milliseconds_now();
for(int i=0; i<numCalls; i++)
XORShift();
long long elapsed = milliseconds_now() - start;
cout << "\tms: " << elapsed << endl;
}
{
cout << "GameRand..." << endl;
long long start = milliseconds_now();
for(int i=0; i<numCalls; i++)
GameRand();
long long elapsed = milliseconds_now() - start;
cout << "\tms: " << elapsed << endl;
}
{
cout << "std::rand..." << endl;
long long start = milliseconds_now();
for(int i=0; i<numCalls; i++)
std::rand();
long long elapsed = milliseconds_now() - start;
cout << "\tms: " << elapsed << endl;
}
}
詳細信息
我正在使用C++和Microsofts「cl」編譯器。我正在測試3個僞隨機函數的性能。它們是XORShift,GameRand和std :: rand()。
建築的main.cpp和randoms.cpp單獨和與所述命令
cl /O2 /Oi main.cpp randoms.cpp
產生以下性能結果鏈接:
XORShift...
ms: 520
GameRand...
ms: 2056
std::rand...
ms: 3800
然而如果忘記了報頭和直接通過包括的功能
#include "randoms.cpp"
並編譯時沒有任何鏈接
cl /O2 /Oi main.cpp
我得到非常不同的表現:
XORShift...
ms: 234
GameRand...
ms: 135
std::rand...
ms: 3823
兩個XORShift和GameRand得到顯着的速度提升。 GameRand的速度比XORShift的速度慢,這很奇怪。我怎樣才能得到2cd測試的速度,但仍然分別編譯random.cpp和鏈接?
** 編輯 **:
由於@sehe的評論以及@Oswald和@TomaszKłak的回答,問題已解決。我正在使用命令編譯
cl /O2 /Oi /GL main.cpp randoms.cpp
/GL標誌執行鏈接時間優化。我可以單獨編譯文件,仍然可以獲得內聯。
谷歌和內聯LTO – sehe
LTO將鏈接單獨的目標文件時生效,這裏我們看到包含實現內聯功能時性能會有所提高。 – tumdum
@sehe。感謝LTO的建議。我將/ GL標誌包含在cl編譯器中。單獨編譯的性能現在匹配單個編譯。如果您將您的評論翻譯成答案,我會接受它。 – mike