调度器
调度器组件是系统中的关键部分,负责通过执行与每个操作符相关的条件来管理图中操作符的执行。其主要职责包括协调图中定义的所有操作符的执行,同时跟踪它们的执行状态。
Holoscan SDK 提供了多种调度器,可以满足各种用例。这些调度器包括
贪婪调度器:这款基础的单线程调度器以贪婪的方式测试条件。它适用于简单的用例,并提供可预测的执行。然而,它可能不适用于大规模应用程序,因为它可能会在条件执行中产生显著的开销。
多线程调度器:多线程调度器旨在处理大规模应用程序中复杂的执行模式。该调度器由一个调度器线程组成,该线程监控每个操作符的状态,并将其分派到负责执行它们的工作线程池。执行完成后,工作线程将操作符放回调度队列。与贪婪调度器相比,多线程调度器提供了卓越的性能和可扩展性。
基于事件的调度器:基于事件的调度器也是一个多线程调度器,但顾名思义,它是基于事件的,而不是基于轮询的。它不是让一个线程不断轮询每个操作符的执行就绪状态,而是等待接收事件,该事件指示操作符已准备好执行。与使用长轮询间隔(
check_recession_period_ms
)的多线程调度器相比,基于事件的调度器将具有更低的延迟,但不会出现短轮询间隔的多线程调度器那样高的 CPU 使用率。
为手头的用例选择合适的调度器至关重要,以确保最佳性能和高效的资源利用率。由于调度器的大多数参数是重叠的,因此可以轻松地在它们之间切换,以测试哪一个对于给定的应用程序可能是最有效的。
贪婪调度器有一些用户可以配置的参数。
调度器使用的时钟可以设置为
realtime
或manual
时钟。实时时钟应用于应用程序,因为它会根据需要暂停执行,以遵守用户指定的条件(例如,具有周期性条件的操作符将等待请求的周期,然后再再次执行)。
手动时钟主要用于测试目的,因为它会导致操作符以时间压缩的方式运行(例如,不遵守周期性条件,操作符立即连续运行)。
用户可以指定一个
max_duration_ms
,这将导致应用程序在指定的最大持续时间后终止执行。-1
的默认值(或任何其他负值)将导致不应用最大持续时间。此调度器还有一个布尔参数
stop_on_deadlock
,用于控制在发生死锁时应用程序是否终止。当所有操作符都处于WAIT
状态,但没有挂起的周期性条件来打破此状态时,就会发生死锁。此参数默认为true
。当设置
stop_on_deadlock_timeout
参数时,调度器将等待此时间量(以毫秒为单位),然后再确定它处于死锁状态并应停止。如果在等待期间有作业进入,它将重置。负值表示不因死锁而停止。此参数仅在stop_on_deadlock=true
时适用。
多线程调度器有几个用户可以配置的参数。这些是 GreedyScheduler
(在上面的章节中描述)可用参数的超集。此处仅描述多线程调度器独有的参数。多线程调度器使用专用线程轮询操作符的状态,并调度任何准备好执行的操作符。当 check_recession_period_ms
接近 0 时,这将导致此轮询线程的 CPU 使用率很高。
调度器使用的工作线程数可以通过
worker_thread_number
设置,默认为1
。这应根据工作流程和可用硬件的考虑来设置。例如,计算图的拓扑将决定可能并行运行多少个操作符。某些操作符可能会在内部启动多个线程,因此可能需要进行一定量的性能分析来确定给定工作流程的最佳参数。check_recession_period_ms
的值控制调度器在再次检查给定条件之前休眠多长时间。换句话说,这是处于WAIT
状态的操作符的轮询间隔。此参数的默认值为5
毫秒。strict_job_thread_pinning
的值控制在使用用户定义的线程池和线程绑定时的行为。如果此值为false
(默认值),则当绑定到线程的操作符未处于 READY 状态时,某些其他未绑定的操作符可以使用该线程。如果为true
,则只有绑定的操作符可以使用该线程。
基于事件的调度器也是一个多线程调度器,但它是基于事件的,而不是基于轮询的。因此,没有 check_recession_period_ms
参数,并且此调度器不会出现短间隔轮询时可能发生的高 CPU 使用率。相反,调度器仅在收到指示操作符已准备好执行的事件时才会唤醒。此调度器的参数是 GreedyScheduler
(如上所述)可用参数的超集。此处仅描述基于事件的调度器独有的参数。
调度器使用的工作线程数可以通过
worker_thread_number
设置,默认为1
。这应根据工作流程和可用硬件的考虑来设置。例如,计算图的拓扑将决定可能并行运行多少个操作符。某些操作符可能会在内部启动多个线程,因此可能需要进行一定量的性能分析来确定给定工作流程的最佳参数。
对于此调度器,没有 strict_job_thread_pinning
选项(请参阅上面多线程调度器的描述)。线程绑定始终是严格的。