求问:是否存在不受strict aliasing规则char豁免限制的8位算术类型?
有没有不会触发strict aliasing优化陷阱的8位算术类型?
使用uint32_t的同功能代码优化效果优于uint8_t,核心原因是uint8_t通常是unsigned char的typedef,而字符类型在strict aliasing规则中享有豁免权,导致编译器无法进行有效优化。
示例代码
using T = uint32_t; T *a; T *b; T *c; void mult(int num) { for (int count = 0; count < num; count++) { a[count] = b[count] * c[count]; } }
uint32_t版本-O1优化后的内层循环汇编
.LBB0_2: # =>This Inner Loop Header: Depth=1 mov r8d, dword ptr [rcx + 4*rdi] imul r8d, dword ptr [rax + 4*rdi] mov dword ptr [rdx + 4*rdi], r8d inc rdi cmp rsi, rdi jne .LBB0_2
该循环仅完成加载值、执行乘法、存储结果的操作,优化效果理想。
uint8_t版本clang生成的内层循环汇编
.LBB0_2: # =>This Inner Loop Header: Depth=1 mov rsi, qword ptr [rip + b] # see here mov rax, qword ptr [rip + c] # see here movzx eax, byte ptr [rax + rdx] mul byte ptr [rsi + rdx] mov rsi, qword ptr [rip + a] # see here mov byte ptr [rsi + rdx], al inc rdx cmp rcx, rdx jne .LBB0_2
可以看到,该循环每次迭代都要重新加载a、b、c的指针值——编译器无法确定指针存储区和指向的内存是否存在别名,因此无法将指针值缓存到寄存器中优化。即使在更高优化级别下,uint16_t和uint32_t会被优化为SIMD/XMM指令,但uint8_t/char的循环依然无法得到有效优化。
问题答案
不存在这样的标准8位算术类型。
C标准中,只有char、signed char和unsigned char这三种类型享有strict aliasing规则的豁免权——这意味着任何类型的指针都可以被这三种字符类型的指针别名访问,反之亦然。而uint8_t在几乎所有平台上都是unsigned char的typedef,自然会触发同样的别名问题。
如果尝试自定义非字符类型的8位整数,这类类型不属于标准的“简单算术类型”,且编译器会将其视为普通非字符类型处理——虽然不会触发别名豁免的问题,但不符合你要求的“简单8位算术类型”定义。
内容的提问来源于stack exchange,提问作者Mike Vine
相关产品推荐
相关产品推荐

