【发布时间】:2018-11-06 19:12:29
【问题描述】:
我正在开发一个在 Windows 上比在 Linux 上慢 3-4 倍的游戏引擎。
我试图分析应用程序,除了 Windows 上的一切似乎更慢之外,我没有看到特别的问题。
我提取了应用程序的一小部分。我用g++ -O3 perf.cpp 编译它并执行如下:a.exe 500000000。结果如下:
- Linux:10 秒(平均 5 次执行):g++ 8.2 [也使用 g++ 7.3 测试]
- Windows:27 秒(5 次执行的平均值):g++(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)8.1.0 [也使用 g++ 7.1 测试]
源代码:
#include <iostream>
#include <cmath>
#include <vector>
#include <chrono>
struct Vector{
float X, Y, Z;
Vector(float X, float Y, float Z) : X(X), Y(Y), Z(Z){}
Vector vector(const Vector &target) const{
return Vector(target.X - X, target.Y - Y, target.Z - Z);
}
float dotProduct(const Vector &v) const{
return (X*v.X + Y*v.Y + Z*v.Z);
}
};
float compute(const std::vector<Vector> &v){
Vector vec1 = v[0].vector(v[2]);
Vector vec2 = v[1].vector(v[0]);
return vec1.dotProduct(vec2);
}
int main(int argc, char *argv[]){
unsigned int loopMax = atoi(argv[1]);
Vector va(1.5f, 3.0f, 8.0f*loopMax);
Vector vb(1.2f, 2.3f, 11.0f*loopMax);
Vector vc(8.2f, 5.0f, 12.0f*loopMax);
auto frameStartTime = std::chrono::high_resolution_clock::now();
float res = 0.0f;
for(unsigned int i=0; i<loopMax; ++i)
{
res += compute({va, vb, vc});
}
auto frameEndTime = std::chrono::high_resolution_clock::now();
auto diffTimeMicroSeconds = std::chrono::duration_cast<std::chrono::microseconds>(frameEndTime - frameStartTime).count();
std::cout<<"Time: "<<diffTimeMicroSeconds / 1000000.0 <<" sec, res: "<<res<<std::endl;
return 0;
}
我知道一次迭代的差异是荒谬的(
什么可以解释这种差异?如何发现问题?
【问题讨论】:
-
为这两种情况生成的程序集可能会有所帮助。此外,您应该将代码作为文本粘贴到您的问题中。
-
您是否在 Windows 上尝试过不同的编译器?我的意思是,gcc 相当不错,但在 Windows 上,Visual Studio 编译器通常更好。也许也可以试试 clang。
-
在循环中,
std::vector<Vector>参数可能会分配给compute。这可能会导致依赖于操作系统/标准库实现的性能。 -
@eukaryota 这可能是它 - 堆分配是有保证的,现在只有 clang 可以做堆省略 AFAIK。
-
-march=native -flto怎么样?