在C中,我们经常使用char来表示小数。然而,处理器总是使用Int(或32位)值来读取寄存器(或从寄存器获取)。因此,每次我们需要在程序中使用一个字符或8位时,处理器需要从regsiter中获取32位,并从其中“解析”8位。因此,如果内存不是限制,那么更多地使用Int代替char是否有意义?它对处理器有帮助吗?
发布于 2014-10-15 08:15:11
来自ARM系统开发人员指南
大多数ARM数据处理操作都是32位的。出于这个原因,您应该尽可能地对局部变量使用32位的数据类型int或long。即使您正在操作一个8位或16位的值,也不要使用char和short作为局部变量类型
书中的一个例子代码证明了这一点。注意对char的环绕处理,而不是无符号int。
int checksum_v1(int *data)
{
char i;
int sum = 0;
for (i = 0; i < 64; i++)
{
sum += data[i];
}
return sum;
}使用i作为char时的ARM7程序集
checksum_v1
MOV r2,r0 ; r2 = data
MOV r0,#0 ; sum = 0
MOV r1,#0 ; i = 0
checksum_v1_loop
LDR r3,[r2,r1,LSL #2] ; r3 = data[i]
ADD r1,r1,#1 ; r1 = i+1
AND r1,r1,#0xff ; i = (char)r1
CMP r1,#0x40 ; compare i, 64
ADD r0,r3,r0 ; sum += r3
BCC checksum_v1_loop ; if (i<64) loop
MOV pc,r14 ; return sum当我是一个未签名的int时,ARM7程序集。
checksum_v2
MOV r2,r0 ; r2 = data
MOV r0,#0 ; sum = 0
MOV r1,#0 ; i = 0
checksum_v2_loop
LDR r3,[r2,r1,LSL #2] ; r3 = data[i]
ADD r1,r1,#1 ; r1++
CMP r1,#0x40 ; compare i, 64
ADD r0,r3,r0 ; sum += r3
BCC checksum_v2_loop ; if (i<64) goto loop
MOV pc,r14 ; return sum发布于 2014-10-15 06:20:45
有编译器部分和cpu部分。
如果您告诉编译器您使用的是char而不是int,那么在静态分析期间,它将知道变量的界限在0-255之间,而不是0-(2^32-1)。这将使它更好地优化您的程序。
在cpu方面,您的假设并不总是正确的。以x86为例,它具有32位寄存器和8位寄存器访问寄存器eax和al。如果您只想使用字符,那么使用al就足够了。没有性能损失。
针对以下评论,我做了一些简单的基准:
艾尔:
format PE GUI 4.0
xor ecx, ecx
dec ecx
loop_start:
inc al
add al, al
dec al
dec al
loopd short loop_start
reteax:
format PE GUI 4.0
xor ecx, ecx
dec ecx
loop_start:
inc eax
add eax, eax
dec eax
dec eax
loopd short loop_start
ret时代:
$ time ./test_al.exe
./test_al.exe 0.01s user 0.00s system 0% cpu 7.102 total
$ time ./test_eax.exe
./test_eax.exe 0.01s user 0.01s system 0% cpu 7.120 total因此,在这种情况下,al稍快一些,但有时eax出现得更快。两者之间的差别实际上是微不足道的。但是cpus并不是那么简单,可能会出现代码对齐问题、缓存和其他问题,所以最好对自己的代码进行基准测试,看看性能是否有改善。但是imo,如果您的代码不是超紧的,最好是信任编译器来优化。
发布于 2014-10-15 07:04:51
如果我是您,我会坚持使用int,因为这可能是您的平台中最本地的集成类型。在内部,您可以期望将较短的类型转换为int,这样实际上会降低性能。
您应该不应该使用char,并且希望它在跨平台上是一致的。尽管C标准将sizeof(char)定义为1,但char本身可以是signed或unsigned。选择取决于编译器。
如果您认为在使用8位类型时可以获得一些性能增益,那么要显式地使用signed char或unsigned char。
https://stackoverflow.com/questions/26375616
复制相似问题