【发布时间】:2019-04-13 13:00:44
【问题描述】:
math.h 中的 cos() 比 x86 asm fcos 运行得更快。
以下代码是 x86 fcos 和 math.h 中 cos() 的比较。
在这段代码中,1000000 次 asm fcos 花费 150ms; 1000000 次 cos() 调用只需 80 毫秒。
fcos 在 x86 中是如何实现的? 为什么 fcos 比 cos() 慢很多?
我的环境是intel i7-6820HQ + win10 + visual studio 2017。
#include "string"
#include "iostream"
#include<time.h>
#include "math.h"
int main()
{
int i;
const int i_max = 1000000;
float c = 10000;
float *d = &c;
float start_value = 8.333333f;
float* pstart_value = &start_value;
clock_t a, b;
a = clock();
__asm {
mov edx, pstart_value;
fld [edx];
}
for (i = 0; i < i_max; i++) {
__asm {
fcos;
}
}
b = clock();
printf("asm time = %u", b - a);
a = clock();
double y;
for (i = 0; i < i_max; i++) {
start_value = cos(start_value);
}
b = clock();
printf("math time = %u", b - a);
return 0;
}
根据我个人的理解,单条asm指令通常比函数调用要快。 为什么在这种情况下 fcos 这么慢?
更新: 我在另一台装有 i7-6700HQ 的笔记本电脑上运行了相同的代码。 在这台笔记本电脑上,1000000 次 fcos 仅花费 51 毫秒。为什么两个cpu差别这么大。
【问题讨论】:
-
查看程序集以了解
cos()会发生什么。 -
至少用你正在使用的实现来标记它,因为除了古怪风格的内联汇编是特定于实现的之外,数学库的性能属性和死代码消除也将是。
-
它可能使用流式 SIMD 扩展而不是旧的、未进一步优化的 x87 指令。
-
哪个 i7 型号?范围从 2008 年的 Nehalem(
fcos解码到 ~100 微秒,需要 40 到 100 个时钟周期)到 2019 年的咖啡湖(fcos 解码到 53 到 105 微秒,需要 50 到 130 个时钟周期)@987654321 @。甚至 Cannon Lake... 数学库cos()可能使用的 SSE2 指令的性能范围很大。 -
@Peter Cordes 我的 CPU 是 i7 6820HQ。今天我尝试在 i7 6700HQ 的笔记本电脑上运行相同的代码。在 6700HQ 笔记本电脑上,asm fcos 花费 51ms。为什么两个cpu差别这么大。
标签: c assembly x86 floating-point x87