解决方案:显然,罪魁祸首是使用floor(),其性能在glibc中依赖于操作系统.
这是前一个问题的后续问题:Linux上的程序速度比Windows快 - 为什么?
我有一个小的C++程序,当用nuwen gcc 4.6.1编译时,在Wine上比在Windows XP上运行得快得多(在同一台计算机上).问题:为什么会发生这种情况?
Wine和Windows的时间分别为~15.8和25.9秒.请注意,我在谈论相同的可执行文件,而不仅仅是相同的C++程序.
源代码在帖子的末尾.编译后的可执行文件在这里(如果你足够信任我).
这个特殊的程序没有任何用处,它只是一个最小的例子,从我有一个更大的程序.请参阅另一个问题,以获得原始程序的一些更精确的基准测试(重要!!)和最常见的可能性排除(例如其他程序在Windows上占用CPU,处理启动损失,系统调用的差异,如内存分配) .另请注意,虽然我在这里使用的rand()是简单,但在原版中我使用了自己的RNG,我知道它没有堆分配.
我在这个主题上提出一个新问题的原因是,现在我可以发布一个实际的简化代码示例来重现这个现象.
代码:
#include <cstdlib>
#include <cmath>
int irand(int top) {
return int(std::floor((std::rand() / (RAND_MAX + 1.0)) * top));
}
template<typename T>
class Vector {
T *vec;
const int sz;
public:
Vector(int n) : sz(n) {
vec = new T[sz];
}
~Vector() {
delete [] vec;
}
int size() const { return sz; }
const …Run Code Online (Sandbox Code Playgroud) 我对系统调用的理解是,在Linux中,系统调用机制(int 0x80或其他)被记录在案,并保证在不同的内核版本中保持稳定.使用此信息,系统调用直接在CRT库中实现,因此当我调用时,printf("a");这涉及对CRT的单个函数调用,其中系统调用被设置并激活.从理论上讲,这可以通过静态编译CRT(在Linux上不常见,但有可能)进一步改进,这样即使单个函数调用也可以内联.
另一方面,Windows不记录甚至不保证系统调用机制的一致性.在Windows上进行系统调用的唯一方法是调用ntdll.dll(或者可能*.dll是其他)从CRT完成的操作,因此涉及两个函数调用.如果静态使用CRT并且函数内联(在Windows上比Linux稍微常见)我们仍然有单个函数调用ntdll.dll,我们无法摆脱.
因此,在我看来理论上,Windows上的系统调用本身就会变慢,因为它们总是要比Linux等效函数执行一次函数调用.这种理解(以及我上面的解释)是否正确?
注意:我纯粹在理论上问这个问题.我理解在进行系统调用时(我认为总是涉及2个上下文切换 - 每个方向一个),额外函数调用的成本可能完全可以忽略不计.