2022+英特尔至强平台:自旋锁忙循环选_mm_pause()还是_tpause()?
自旋锁忙循环:
_mm_pause() vs _tpause() 选择建议 针对你2022年后英特尔至强平台、追求性能最大化不在乎功耗的场景,直接给出结论:优先使用 _mm_pause(),原因如下:
核心差异分析
_mm_pause():专门为自旋循环优化的指令,无参数,典型延迟约140周期(不同至强型号略有浮动)。它会告诉CPU当前处于自旋等待状态,避免激进推测执行导致的流水线清空损失,同时优化缓存窥探行为、减少无效总线流量,全程保持核心高主频活跃,完全匹配你性能优先的需求。_tpause():设计初衷是低功耗等待,需要传入基于TSC的时间参数。它会让核心进入低功耗空闲状态(如C1E),直到指定时间到期或缓存事件触发。但进入/退出低功耗状态存在固定开销——如果锁能快速获取,这个开销会远大于_mm_pause()的延迟,反而拖慢性能。
若硬要尝试_tpause()的正确用法
尽管不推荐,但如果想测试_tpause(),可以用它模拟_mm_pause()的延迟时长,代码示例如下:
#include <immintrin.h> while(try_lock() == false) { // 获取当前TSC计数器值 uint64_t current_tsc = __rdtsc(); // 设定等待140个TSC周期(对齐_mm_pause()的典型延迟) uint64_t target_tsc = current_tsc + 140; // 参数0表示使用TSC计时,第二个参数为目标TSC值 _tpause(0, target_tsc); }
注意:由于_tpause()会触发核心降频/进入低功耗,实际等待时间可能偏离设定值,且唤醒开销会抵消性能收益。只有当锁会被持有极长时间(远大于低功耗状态进出开销)时它才可能有意义,但这种场景更适合用操作系统休眠原语(如futex)而非自旋锁。
关于_tpause()的延迟数据
Intel官方文档未给出_tpause()的固定延迟值,因为它的实际耗时取决于传入的TSC参数,以及核心进入/退出低功耗状态的开销。对于自旋锁这类短等待场景,它的实际延迟会显著高于_mm_pause()。
最终推荐代码
直接在忙循环中加入_mm_pause()即可:
while(try_lock() == false) { _mm_pause(); }
内容的提问来源于stack exchange,提问作者user997112
相关产品推荐
相关产品推荐

