查看源码 scheduler (runtime_tools v2.1.1)
测量调度器利用率
此模块包含用于轻松测量和计算调度器利用率的实用函数。它充当更原始 API erlang:statistics(scheduler_wall_time)
的包装器。
最简单的用法是调用阻塞的 scheduler:utilization(Seconds)
。
对于非阻塞和/或连续计算调度器利用率,建议的用法是
- 首先调用
erlang:system_flag(scheduler_wall_time, true)
以启用调度器实际时间测量。 - 调用
get_sample/0
以收集样本,并在样本之间留出一些时间。 - 调用
utilization/2
以计算两个样本之间的时间间隔内的调度器利用率。 - 完成后,调用
erlang:system_flag(scheduler_wall_time, false)
以禁用调度器实际时间测量,并避免不必要的 CPU 开销。
要从 utilization/2
获取正确的值,重要的是在两个样本之间的整个时间间隔内保持 scheduler_wall_time
启用。为确保这一点,调用 erlang:system_flag(scheduler_wall_time, true)
的进程必须保持活动状态,因为如果该进程终止,scheduler_wall_time
将自动禁用。
概要
类型
包含各个调度器结果以及汇总平均值的元组列表。Util
是调度器的利用率,表示为 0.0 到 1.0 之间的浮点值。Percent
是相同的利用率,表示为更易于阅读的百分比字符串。
函数
返回正常调度器和脏 CPU 调度器的调度器利用率样本。如果系统标志 scheduler_wall_time
尚未启用,则返回 undefined
。
返回所有调度器(包括脏 IO 调度器)的调度器利用率样本。如果系统标志 scheduler_wall_time
尚未启用,则返回 undefined
。
返回正常调度器和脏 CPU 调度器的调度器利用率样本。如果尚未启用,将首先调用 erlang:system_flag(scheduler_wall_time, true)
。
返回所有调度器(包括脏 IO 调度器)的调度器利用率样本。如果尚未启用,将首先调用 erlang:system_flag(scheduler_wall_time, true)
。
测量在 Seconds
秒内正常调度器和脏 CPU 调度器的利用率,然后返回结果。
计算从调用 get_sample/0
或 get_sample_all/0
获取的两个样本之间的时间间隔内的调度器利用率。
类型
-type sched_id() :: integer().
-opaque sched_sample()
-type sched_type() :: normal | cpu | io.
-type sched_util_result() :: [{sched_type(), sched_id(), float(), string()} | {total, float(), string()} | {weighted, float(), string()}].
包含各个调度器结果以及汇总平均值的元组列表。Util
是调度器的利用率,表示为 0.0 到 1.0 之间的浮点值。Percent
是相同的利用率,表示为更易于阅读的百分比字符串。
{normal, SchedulerId, Util, Percent}
- 编号为SchedulerId
的正常调度器的调度器利用率。也包括未上线的调度器。在线调度器 具有最低的SchedulerId
。{cpu, SchedulerId, Util, Percent}
- 编号为SchedulerId
的脏 CPU 调度器的调度器利用率。{io, SchedulerId, Util, Percent}
- 编号为SchedulerId
的脏 IO 调度器的调度器利用率。仅当两个样本均使用sample_all/0
获取时,此元组才会存在。{total, Util, Percent}
- 所有正常和脏 CPU 调度器的总利用率。{weighted, Util, Percent}
- 所有正常和脏 CPU 调度器的总利用率,根据可用的最大 CPU 时间进行加权。
函数
-spec get_sample() -> sched_sample() | undefined.
返回正常调度器和脏 CPU 调度器的调度器利用率样本。如果系统标志 scheduler_wall_time
尚未启用,则返回 undefined
。
-spec get_sample_all() -> sched_sample() | undefined.
返回所有调度器(包括脏 IO 调度器)的调度器利用率样本。如果系统标志 scheduler_wall_time
尚未启用,则返回 undefined
。
-spec sample() -> sched_sample().
返回正常调度器和脏 CPU 调度器的调度器利用率样本。如果尚未启用,将首先调用 erlang:system_flag(scheduler_wall_time, true)
。
注意
不建议使用此函数,因为无法检测
scheduler_wall_time
是否已启用。如果两个样本之间scheduler_wall_time
已禁用,将其传递给utilization/2
将产生无效结果。请改用
get_sample/0
以及erlang:system_flag(scheduler_wall_time, _)
。
-spec sample_all() -> sched_sample().
返回所有调度器(包括脏 IO 调度器)的调度器利用率样本。如果尚未启用,将首先调用 erlang:system_flag(scheduler_wall_time, true)
。
注意
出于与
sample/0
相同的原因,不建议使用此函数。请改用get_sample_all/0
以及erlang:system_flag(scheduler_wall_time,_)
。
-spec utilization(Seconds) -> sched_util_result() when Seconds :: pos_integer(); (Sample) -> sched_util_result() when Sample :: sched_sample().
测量在 Seconds
秒内正常调度器和脏 CPU 调度器的利用率,然后返回结果。
将自动先启用,然后禁用 scheduler_wall_time
。
计算从获取 Sample
到“现在”的时间间隔内的调度器利用率。与调用 scheduler:utilization(Sample, scheduler:sample_all())
相同。
注意
不建议使用此函数,因为它很容易在没有注意到的情况下获得无效结果。特别是不要执行以下操作
scheduler:utilization(scheduler:sample()). % DO NOT DO THIS!
上面的示例快速连续获取两个样本,并计算它们之间的调度器利用率。得到的值可能比提供的信息更具误导性。
请改用
scheduler:utilization/2
并调用get_sample/0
以在样本之间留出一些时间。
-spec utilization(Sample1, Sample2) -> sched_util_result() when Sample1 :: sched_sample(), Sample2 :: sched_sample().
计算从调用 get_sample/0
或 get_sample_all/0
获取的两个样本之间的时间间隔内的调度器利用率。
此函数本身不需要启用 scheduler_wall_time
。但是,要获得正确的结果,必须在两个样本之间的整个时间间隔内启用 scheduler_wall_time
。