在C语言中,我们通常使用char来表示小型数字。然而,处理器总是使用Int(即32位)值从寄存器中读取(或获取)数据。因此,每次我们的程序需要使用char或8位时,处理器都需要从寄存器中获取32位,并从中“解析”出8位。
因此,如果内存不是限制,更经常地使用Int代替char是否有意义呢?这会对处理器有所“帮助”吗?
因此,如果内存不是限制,更经常地使用Int代替char是否有意义呢?这会对处理器有所“帮助”吗?
有编译器部分和CPU部分。
如果您告诉编译器您正在使用char
而不是int
,在静态分析期间,它将知道变量的边界在0-255之间,而不是0-(2 ^ 32-1)。这将使它更好地优化您的程序。
在CPU方面,您的假设并不总是正确的。以x86为例,它具有寄存器eax
和al
,用于32位和8位寄存器访问。如果您只想使用chars,则使用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
ret
eax:
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
会更快。差异真的微不足道。但是 CPU 并不是那么简单,可能存在代码对齐问题、缓存和其他一些问题,因此最好对自己的代码进行基准测试,以查看是否有性能提升。但我认为,如果你的代码不是非常紧密,最好相信编译器来优化。
char
,那么转换为int
在时间和程序空间上都是代价高昂的。因此,在RAM/flash内存使用和性能之间存在权衡。 - user694733eax
和 al
的操作速度相同。 - Potatoswattersigned char
或unsigned char
。那么问题是什么?;) 编辑你的编辑:编译器定义,但选择由环境(特别是CPU架构)决定。 - dheinint
将是最简单(也是前瞻性的)解决方案。int_fast8_t x;
uint_fast8_t y;
signed和unsigned是保证能够存储至少8位数据并使用通常更快的基础类型的类型。当然,这完全取决于您之后对数据的处理方式。
例如,在我测试过的所有系统上(请参见:C ++中的标准类型大小),快速类型都是8位长的。
来自ARM系统开发人员指南:
大多数ARM数据处理操作仅支持32位。因此,尽可能使用32位数据类型int或long作为本地变量。即使您正在操作8位或16位值,也应避免使用char和short作为本地变量类型。
以下是书中的示例代码以证明这一点。请注意,与unsigned int相比,char的环绕处理方式不同。
int checksum_v1(int *data)
{
char i;
int sum = 0;
for (i = 0; i < 64; i++)
{
sum += data[i];
}
return sum;
}
使用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
当i是无符号整数时,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