在事件循环中使用暂停器
问题描述
在典型的应用程序堆栈中,多个线程用于服务事件、处理数据、流水线等。一个重要的设计考虑是线程如何意识到有工作要做,一些通用方法包括:
- 信号/通知:在这种情况下,接收线程让步(即,被添加到等待队列)直到被另一个线程通知。这样做的好处是资源消耗低;然而,有至少 20-50 微秒(可能更多——见下文)的相对较高的延迟来重新安排线程以响应信号。
- 忙等待:在这种情况下,接收线程不断旋转,检查是否有工作要做的迹象。当线程有工作要做时,这具有快速响应(低延迟)的好处;然而,它是以高 CPU 使用率为代价的,在无事可做时浪费周期。此外,持续的高 CPU 使用率反过来会导致明显更高的电力需求和相关的冷却负载。
- Fixed Sleep:在这种情况下,当没有进一步的工作要做时,接收线程会休眠一段固定的时间,然后再次检查是否有更多的工作。这具有低资源使用率的优势,但这种策略的明显缺点是最坏情况下的延迟至少与睡眠周期一样大。
睡眠问题,以及如何睡得香
线程请求休眠时的实际行为不仅因平台而异,而且因同一平台的不同版本和使用模式而异。
例如,POSIX 要求睡眠调用始终让出 CPU,而 Linux 允许睡眠实现(包括睡眠、usleep、nanosleep 等)在某些情况下忙于等待。对于具有固定计时器滴答声(通常为 100Hz、250Hz 或 1000Hz)的旧版本 Linux,屈服于调度程序时会有相对较大的惩罚,这鼓励在短时间内在睡眠调用中使用内部忙等待。相比之下,较新版本的 Linux 具有使用动态滴答的更复杂的调度程序,可以与休眠线程进行更准确的短期交互,这在很大程度上消除了忙等待以实现低休眠期的需要。
以下经验法则通常适用于标准进程的最新 Linux 版本(即那些在标准调度程序下以正常权限运行的进程):
- ~1us 的睡眠请求原则上可以合理准确地得到服务
- 一般来说,即使是很短的睡眠时间也不会忙等待,尽管极短的睡眠时间几乎肯定会
- 与忙等待 (100%) 相比,~1ms 和~1us 的睡眠请求将 CPU 使用率分别降低到~1% 和~10%
虽然上面表明即使相对较短的 ~1us 睡眠也可能在延迟和资源使用之间提供有用的折衷,但主要问题是调度——一旦睡眠进程完全上下文关闭内核,重新调度的开销可以是数量级高于预期的睡眠时间。
同样,对于系统将如何运行,没有单一的答案。关键是尽量偏向情况,避免线程从一个核心切换,以及使用线程亲和性(避免线程被移动到另一个核心)和CPU隔离(避免另一个进程/线程争用线程)在这种情况下非常有效。(其他选项包括以实时优先级运行;但是,我们希望尽可能将本文档的重点放在标准设置上。)
谨慎使用亲和力、隔离和较短的睡眠周期可以产生响应迅速、低抖动的环境,与繁忙等待相比,这种环境使用的 CPU 资源要少得多。
什么是暂停器?
Chronicle 的 Pausers——一种开源产品——通过使用智能退避策略在信号/通知、固定睡眠和忙等待的上述极端行为之间提供滑动规模的行为,该策略可以实现更细微的控制以更好地平衡低延迟和资源利用率。
一般的策略是忙等待一小段时间,然后在没有工作可做时逐渐退回到越来越长的暂停(消耗越来越少的 CPU)。根据任务的不同,可以使用不同的策略(暂停模式),使用暂停的规范方式是:
暂停模式
Chronicle Pausers 允许针对给定级别的响应性和延迟优化 CPU 负载。可以高精度地配置此权衡,而无需对您的应用程序代码进行重大更改。例如,如果您意识到特定线程需要更快的响应,则可以将其暂停器从退避暂停器更改为忙碌暂停器,反之亦然。
值得注意的是,用于内部最低延迟的 Busy Pauser 使用忙等待,因此将消耗 100% 的一个内核。因此,重要的是要确保 Busy Pausers 不会争用相同的内核,并且在使用 Busy Pausers 控制这方面时应考虑 CPU 亲和力和隔离。可以在此处找到有关 CPU 隔离及其在事件循环中的优势的更多信息。
暂停模式的表现
下图绘制了等待事件的时间(x 轴)与选择暂停器的暂停/响应时间的关系。
Busy、TimedBusy、Yielding 和 Millis Pausers 显示平坦的响应时间,无论线程等待接收事件的时间长短,但由于不同的让出策略与 CPU 使用率,响应时间也不同。在许多情况下,TimedBusy 尤其在低延迟和 CPU 使用率之间提供了极好的折衷。
Sleepy 和 Balanced 策略显示了响应时间的阶跃变化和稳定增长,反映了线程等待接收事件的时间越长,增量回退。
在事件循环中使用暂停器相关推荐
- 事件循环中的宏任务和微任务执行顺序
事件循环中的宏任务和微任务执行顺序 先来了解一下事件循环.宏任务.微任务和Promise 1.事件循环(Event Loop)运行机制 执行一个宏任务(栈中没有就从事件队列中获取) 执行过程中如果遇到 ...
- 探究点击事件在JavaScript事件循环中的表现
JavaScript的事件循环event loop很多文章都写的非常详细了.这里也不多做介绍. 在很多文章中都有介绍鼠标事件Mouse Event是属于macrotask.本文探究一下Mouse Ev ...
- JS事件循环中的宏任务和微任务执行顺序
1. 宏任务和微任务事件 其中微任务的优先级高于宏任务,括号内为事件运行环境 宏任务 微任务 I/O事件/onClick点击事件 process.netTick (Node) setTimeout N ...
- 【nodejs原理源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick
[摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...
- vue openlayer单击地图事件循环多次执行_Vue中$nextTick的理解
Vue中$nextTick方法将回调延迟到下次DOM更新循环之后执行,也就是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,能够获取更新后的DOM.简单来说就是当数据更新时, ...
- JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!...
此篇是 JavaScript是如何工作的第四篇,其它三篇可以看这里: JavaScript是如何工作的:引擎,运行时和调用堆栈的概述! JavaScript是如何工作的:深入V8引擎&编写优化 ...
- JavaScript 如何工作的: 事件循环和异步编程的崛起 + 5 个关于如何使用 async/await 编写更好的技巧...
原文地址:How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding wi ...
- [译] JavaScript 如何工作的: 事件循环和异步编程的崛起 + 5 个关于如何使用 async/await 编写更好的技巧...
原文地址:How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding wi ...
- JavaScript 异步执行的学习笔记 - 什么是事件循环 Event loop?
原文 使用像 JavaScript 这样的语言进行编程时,最重要但也经常被误解的部分之一是如何表达和操作一段需要某段时间才能完成执行的程序行为. 这不仅仅是从 for 循环开始到 for 循环结束发生 ...
最新文章
- 【错误记录】Kotlin 1.5.0 编译报错 ( 1.5.0 中 Float 不能直接转 Byte 类型 )
- java字符串转化为数组_Go 语言字符串和数组转化 | 臭大佬
- java 短信猫发送短信的方法
- python123 helloworld_python入门
- python怎么创建txt文件啊_python根据txt文本批量创建文件夹
- React之createRef
- 大便的离去,是马桶的追求?还是肛门的不挽留?
- 勿以善小而不为--PPP认证之CHAP与PAP的实现与区别
- QT5-STK二次开发实例
- 基于 Flink SQL CDC的实时数据同步方案
- 记MySQL表空间碎片清理过程
- 金融×科技,成就大未来!
- 滴滴夜莺发布v3.3.0版本
- mysql 改列定义_如何更改MySQL列定义?
- 关于enq: US – contention
- 电磁场仿真软件ANSYS Electronics下载附安装教程
- Windows XP 下载
- 大数据学习之环境构建
- 程序员如何正确饲养乌龟?
- Mysql数据库存储ip地址
热门文章
- Application工具方法
- uniapp h5端兼容pc端
- 合规运营必备资质——ICP申请指南
- oracle auto failover,Oracle学习之DATAGUARD(九) 自动Failover
- 双击EXCEL 文件打不开,要先打开EXCEL才能打开EXCEL文件
- Hallucinated-IQA
- Android Socket 连接设备接收H264裸流数据并解码播放 Demo
- 会议活动主题着陆页HTML5模板
- 北京老年旅游消费画像:近95%老年人有一次以上旅游经历 50%游客人均消费超五千
- locust2.0+教程:007 - 分布式压测执行