【发布时间】:2023-03-24 01:24:01
【问题描述】:
问题:为什么我单独编译和链接时函数的性能会不同?
首先,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++ 和微软的“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 和@Tomasz Kłak 的回答,问题得以解决。我现在正在用命令编译
cl /O2 /Oi /GL main.cpp randoms.cpp
/GL 标志执行链接时间优化。我可以单独编译文件,仍然可以得到内联。
【问题讨论】:
-
google 内联和 LTO
-
LTO 将在链接单独的目标文件时生效,在这里我们看到包含实现 - 内联时的性能提升。
-
@sehe。感谢 LTO 的建议。我在 cl 编译器中包含了 /GL 标志。单独编译的性能现在与单次编译匹配。如果您将您的评论翻译成答案,我会接受。
标签: c++ windows performance build