独立于架构的自旋等待循环

针对多核处理器,本文探讨了自旋等待循环在游戏开发中的应用及优化策略,特别是面对指令延迟变动时的应对措施,提供了改进的自旋循环代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

独立于架构的自旋等待循环

由 Jon Kennedy. (Intel)IDZSupport K. 发布于 2018 年 4 月 26 日

 

翻译简体中文繁体中文英语法语德语意大利语葡萄牙语俄语西班牙语土耳其语

翻译

为了充分利用当今多核处理器的功能,游戏开发人员正使用更高级的任务处理系统使工作分散到线程池的多个线程之中。随着线程数量的增加,诸如任务队列锁和其他共享资源结构上的线程之间发生争用的可能性也会增加。有多种解决办法,但是自旋等待循环是常见的结构。

1while (!acquire_lock())
2{
3    // Spin for a specific number of iterations
4    for (int i = 0; i < max_spin_count; i++)
5    {
6        // Pause intrinsic
7        _mm_pause();
8    }
9}

本文使用了 The _mm_pause 指令,因为它可以提示处理器调用线程位于自选等待循环中。这将暂停下一条指令的执行,不再需要处理器,也不会使用部分管线,因此降低了能耗。

_mm_pause 指令在多数前几代英特尔平台上拥有相似的延迟。由于存在这种历史一致性,许多开发人员在调整自旋循环时会考虑到这一点。但是,从第六代智能英特尔® 酷睿™ i 处理器产品家族开始,pause 指令的延迟增加了多个数量级,旨在为许多场景提供更好的节能机会。

由于延迟发生了变化,以上固定数量的自旋循环将消耗比之前高一个数量级的周期,这将对您的应用性能造成不利影响。为了避免未来的指令架构变动引起任何问题,对所有自旋等待循环进行检查,以确保未使用固定数量的 pause 指令实施它们。可以对上述自旋等待循环进行以下适当修改:

01while (!acquire_lock())
02{
03    // __rdtsc intrinsic is used to read the time stamp counter
04    // This allows the loop to run for a fixed number of cycles
05    uint64_t prev = __rdtsc();
06    do
07    {
08        // Pause intrinsic
09 
10        _mm_pause();
11    }
12    while ((__rdtsc() - prev) < max_spin_time)
13    }

尽管上述自旋等待循环非常简单,软件开发人员一般会使用更高级的自旋循环(支持指数退避等),但是它展示了如何使软件变得更强大,以应对未来指令延迟的架构变动。

 

请参阅以下文章,进一步了解 _mm_pause 指令与自旋等待循环:有益于功耗与性能的睡眠循环

如欲获取关于英特尔® 架构编程的更多信息,请参阅以下软件开发手册:《64 位和 32 位英特尔®架构软件开发人员手册》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值