运行时线程处理模型
了解运行时线程、池和调度规则如何影响 NetLogic 执行、任务选择和性能。
概述
FactoryTalk Optix 应用程序
使用多种执行模型。运行时工作不会在一个全局线程上运行。运行时使用基于优先级的共享线程池、计时器池和专用子系统线程。此模型会影响 NetLogic 代码的运行方式、回调的序列化方式,以及系统负载如何改变应用程序行为。
共享线程池和专用线程
基于优先级的共享线程池运行常规运行时工作。运行时按优先级和可用工作线程来调度工作。计时器池处理基于计时器的回调。某些子系统使用专用线程而不是共享池。
专用子系统线程可隔离必须保持响应性或顺序性的工作。通信驱动程序可以根据驱动程序设计和协议需求使用自己的线程处理模型。
调度和序列化
运行时对许多操作使用基于亲和性的调度。以同一运行时对象或执行上下文为目标的工作可以在同一亲和性下按序列化顺序运行。序列化减少了对同一状态的并发访问,但这并不意味着所有运行时工作都在一个线程上运行。
独立的对象或子系统可以在不同的线程上并行运行。当代码可从不同上下文运行时,共享资源仍需要采用线程安全设计。
NetLogic 执行模型
NetLogic 代码可以从不同的运行时上下文中运行。
Start()
和 Stop()
遵循 NetLogic 生命周期 中所述的 NetLogic 生命周期规则。导出的方法、事件回调、计时器和异步任务可以根据调用方和运行时计划程序在不同的线程上运行。不要假定后续调用会重用同一线程。设计 NetLogic 代码,以便在可能发生并发访问时,共享状态为显式、受限且受到保护。
长期运行的工作
LongRunningTask
是必须访问信息模型的长期运行或阻塞性操作的首选选项。它将长期运行的工作与生命周期执行分离,并有助于保持运行时行为的响应能力。仅对不访问项目节点的工作使用
async/await
或 .NET 线程池 API。有关 API 详细信息,请参见构造函数:LongRunningTask(action, executingNode)。硬件注意事项
运行时吞吐量取决于 CPU 核心计数和 CPU 时钟速度。核心越多,潜在并行度就越高。更高的时钟速度可提高单线程性能和串行工作负载的性能。
超线程或同时多线程 (SMT) 可以提高 CPU 利用率,但逻辑核心的性能无法与更多物理核心的性能相匹配。性能提升取决于工作负载类型、阻塞性行为和争用情况。
设计原则
设计用于执行运行时的 NetLogic 代码时,请遵循以下原则:
- 保持Start()和Stop()简短。
- 将阻塞性或长期运行的工作移至LongRunningTask或其他合适的任务类型。
- 避免对跨子系统的线程标识或回调顺序做出假设。
- 保护共享的可变状态。
- 减少对共享资源的争用。
- 在实际 CPU 负载、I/O 负载和通信负载下进行测试。
threading model
thread pool
timer pool
NetLogic
LongRunningTask
communication driver
performance
提供反馈