32位的比较比64位的比较快吗?
我在看这个文件http://www.netlib.org/fdlibm/s_cos.c
他们有这段代码
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
Run Code Online (Sandbox Code Playgroud)
我理解第一行,它计算x的绝对值。但为什么比较如此复杂?通过比较前 32 位而不是全部 64 位,性能是否有任何改进?我能写吗
long unsigned int ix = *(long unsigned int * (&x));
ix &= 0x7fffffffffffffff;
if (ix < 3fe921fb54442d18)
/* What comes next */
Run Code Online (Sandbox Code Playgroud)
并期望在 64 位机器上获得相同的速度性能?虽然我同意这会消耗更多内存。
0x3fe921fb54442d18 是 pi/2。
在我的 64 位 Intel 机器上,Apple clang version 12.0.0我尝试运行ix <= 0x3fe921fbwhere多次ix输入int超过十亿次。然后我尝试ix < 0x3fe921fb54442d18以相同的unsigned long次数运行ix。以下是几秒钟的结果:
无优化 32 位:
1.470922
1.448247
1.449718
1.446084
1.450020
1.453608
Run Code Online (Sandbox Code Playgroud)
无优化 64 位:
1.567637
1.561653
1.565024
1.575094
1.567794
1.564141
Run Code Online (Sandbox Code Playgroud)
-O332位:
0.421903
0.419469
0.425281
0.419894
0.425790
0.424800
Run Code Online (Sandbox Code Playgroud)
-0364 位:
0.636965
0.640522
0.637279
0.634344
0.634989
0.633755
Run Code Online (Sandbox Code Playgroud)
32 位比较,至少在我的机器上,始终稍快一些。
我会选择第一个选择。即使在 64 位机器上,无论优化设置如何,速度也更快,并且使用的内存和功耗也更少,因为 32 位比较电路更小,消耗的能量更少。另请注意,long unsigned int ix = *(long unsigned int *)(&x);类型double化在技术上x是未定义的行为。
测试代码:
volatile int ix = 0; // Changing this value has no effect
clock_t before = clock();
for (int i = 1<<30; i--;) {
volatile int sink = ix <= 0x3fe921fb;
}
printf("%f\n", (double)(clock()-before)/CLOCKS_PER_SEC);
Run Code Online (Sandbox Code Playgroud)
volatile unsigned long ix = 0;
clock_t before = clock();
for (int i = 1<<30; i--;) {
volatile int sink = ix < 0x3fe921fb54442d18;
}
printf("%f\n", (double)(clock()-before)/CLOCKS_PER_SEC);
Run Code Online (Sandbox Code Playgroud)