Clang优化重复RDTSC汇编块是否合法?技术验证分析
RDTSC汇编块重复使用时的编译器优化问题及解决方法
- Clang编译器(即使开启
-O1优化)会将重复的RDTSC汇编块判定为输出结果相同,进而执行优化,导致两次读取的时间戳差值为0;关闭优化后可得到符合预期的递增时间戳。 - GCC编译器在仅使用两次相同汇编块时不会出现问题,但连续添加第三个相同汇编块后,会认为该汇编块无外部副作用,直接复用第二个汇编块的结果作为第三个时间戳的值。
- 在C语言编译模式下,GCC与Clang都会对重复的RDTSC汇编块执行优化。
经测试验证,编译器会对未用volatile修饰的相同asm语句执行公共子表达式消除(Common-Subexpression Elimination),因此包含RDTSC指令的asm语句必须添加volatile修饰,才能避免此类错误优化。
测试代码示例
volatile size_t tick1; asm ( "rdtsc\n" // 将时间戳存入EDX:EAX寄存器 "shl $32, %%rdx\n" // 将高位部分左移32位 "or %%rdx, %q0" // 合并高低位到目标变量 : "=a" (tick1) : : "rdx"); this_thread::sleep_for(1s); volatile size_t tick2; asm ( "rdtsc\n" // Clang优化器会认为这段汇编的输出和上面相同 "shl $32, %%rdx\n" // 直接将之前的结果加载到tick2的内存地址 "or %%rdx, %q0" // 对应汇编指令:mov qword ptr [rsp + 8], rbx : "=a" (tick2) : : "rdx"); printf("tick2 - tick1 差值 : %zu 时钟周期\n", tick2 - tick1); printf("CPU 时钟频率 : %.2f GHz\n\n", (double) (tick2 - tick1) / 1'000'000'000.);
内容的提问来源于stack exchange,提问作者sandthorn
相关产品推荐
相关产品推荐

