我有一段代码,在Windows上运行速度比在linux上快2倍.这是我测量的时间:
g++ -Ofast -march=native -m64
29.1123
g++ -Ofast -march=native
29.0497
clang++ -Ofast -march=native
28.9192
visual studio 2013 Debug 32b
13.8802
visual studio 2013 Release 32b
12.5569
Run Code Online (Sandbox Code Playgroud)
这似乎是一个太大的差异.
这是代码:
#include <iostream>
#include <map>
#include <chrono>
static std::size_t Count = 1000;
static std::size_t MaxNum = 50000000;
bool IsPrime(std::size_t num)
{
for (std::size_t i = 2; i < num; i++)
{
if (num % i == 0)
return false;
}
return true;
}
int main()
{
auto start = std::chrono::steady_clock::now();
std::map<std::size_t, bool> value; …Run Code Online (Sandbox Code Playgroud) 整数除法的硬件指令历来非常慢。例如,对于 64 位输入,Skylake 上的 DIVQ 延迟为 42-95 个周期 [1](吞吐量倒数为 24-90)。
然而,有更新的处理器,其性能要好得多:Goldmont 具有 14-43 延迟,Ryzen 具有 14-47 延迟 [1],M1 显然具有“每分频 2 个时钟周期的吞吐量”[2],甚至 Raspberry Pico 也具有“8 -循环有符号/无符号除法/模电路,每个核心”(尽管这似乎适用于 32 位输入)[3]。
我的问题是,发生了什么变化?是否发明了新的算法?无论如何,新处理器采用什么算法进行除法?
[1] https://www.agner.org/optimize/#manuals
[2] https://ridiculousfish.com/blog/posts/benchmarking-libdivide-m1-avx512.html
[3] https://raspberrypi。 github.io/pico-sdk-doxygen/group__hardware__divider.html#details
我如何告诉MSVC编译器使用64位/ 32位除法运算来为x86-64目标计算以下函数的结果:
#include <stdint.h>
uint32_t ScaledDiv(uint32_t a, uint32_t b)
{
if (a > b)
return ((uint64_t)b<<32) / a; //Yes, this must be casted because the result of b<<32 is undefined
else
return uint32_t(-1);
}
Run Code Online (Sandbox Code Playgroud)
我希望代码在if语句为true时编译为使用64位/ 32位除法运算,例如:
; Assume arguments on entry are: Dividend in EDX, Divisor in ECX
mov edx, edx ;A dummy instruction to indicate that the dividend is already where it is supposed to be
xor eax,eax
div ecx ; EAX = EDX:EAX / ECX
Run Code Online (Sandbox Code Playgroud)
...但是x64 …
performance ×2
x86 ×2
32bit-64bit ×1
arm ×1
benchmarking ×1
c ×1
c++ ×1
visual-c++ ×1
x86-64 ×1