关于uint_fast*_t类型族,C标准还不太清楚.在gcc-4.4.4 linux x86_64系统上,类型uint_fast16_t和uint_fast32_t大小均为8个字节.但是,8字节数的乘法似乎比4字节数的乘法慢得多.以下代码演示了:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int
main ()
{
uint_least16_t p, x;
int count;
p = 1;
for (count = 100000; count != 0; --count)
for (x = 1; x != 50000; ++x)
p*= x;
printf("%"PRIuLEAST16, p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到了在程序上运行time命令
real 0m7.606s
user 0m7.557s
sys 0m0.019s
Run Code Online (Sandbox Code Playgroud)
如果我将类型更改为uint_fast16_t(和printf修饰符),则时间变为
real 0m12.609s
user 0m12.593s
sys 0m0.009s
Run Code Online (Sandbox Code Playgroud)
那么,如果stdint.h头文件uint_fast16_t(以及uint_fast32_t)定义为4字节类型,那会不会更好?
当我编译这段代码时
unsigned char A[] = {1, 2, 3, 4};
unsigned int
f (unsigned int x)
{
return A[x];
}
Run Code Online (Sandbox Code Playgroud)
gcc输出
mov edi, edi
movzx eax, BYTE PTR A[rdi]
ret
Run Code Online (Sandbox Code Playgroud)
在x86_64机器上.
问题是:为什么有nop指令(mov edi,edi)?
我正在使用gcc-4.4.4.
考虑以下C代码:
#include <stdint.h>
uint32_t inc(uint16_t x) {
return x+1;
}
Run Code Online (Sandbox Code Playgroud)
当使用gcc-4.4.3在纯x86_64系统上使用标志-std = c99 -march = core2 -msse4.1 -O2 -pipe -Wall进行编译时,它会生成
movzwl %di,%eax
inc %eax
retq
Run Code Online (Sandbox Code Playgroud)
现在,在C中预测无符号溢出.我不太了解x86_64汇编,但据我所知,16位参数寄存器被移动到32位寄存器,该寄存器递增并返回.我的问题是,如果x == UINT16_MAX怎么办.会发生溢出,标准规定x + 1 == 0,对吗?但是,如果%eax是一个32位寄存器,它现在包含UINT16_MAX + 1,这是不正确的.
这让我在这里连接一个问题:是否有一种可移植的方法来禁用C中的无符号溢出,以便编译器可以假设存储在大寄存器中的小变量的高位始终为0(所以它不需要清除它们)?如果不是(或者如果解决方案在语法上是令人讨厌的),至少在GCC中有没有办法做到这一点?
非常感谢您的宝贵时间.