本节包含帮助您在多核或多处理器硬件上使用 HALCON 的其他信息。
借助 HALCON 的系统参数(可分别使用 set_system 和 get_system 算子进行设置和查询),您可以自定义并行化机制的行为。
您可以查询处理器(或内核)的数量 通过调用:
get_system('processor_num', Information)
您可以使用算子 set_system 关闭 HALCON 的部分功能。要关闭自动并行化机制,请调用(HDevelop 符号,更多信息请参阅参考手册):
set_system('parallelize_operators','false')
要关闭重入,请调用:
set_system('reentrant','false')
当然,也可以通过调用 set_system(第二个参数为 "true")再次开启这两种行为。请注意,在关闭重入功能的同时,也会关闭自动并行化功能,因为它需要重入功能。
如果您的多线程程序自己进行调度,而不希望 HALCON 通过自动并行化进行干扰,那么就可以关闭自动并行化机制。请注意,在单处理器或单内核计算机上使用 HALCON 时,无需关闭自动并行化机制;如果 HALCON 只检测到一个处理器或内核,则会自动关闭自动并行化机制。
在关闭自动并行化时,可以考虑关闭线程池的使用(参见 set_system 的参数 "thread_pool")。
! 如果已经开启了重入功能,请不要再开启。 否则,这将重置并行化系统,包括开启算子自动并行化。这将降低手动并行化(多线程)的性能。
使用系统参数 "parallelize_operators" ,可以更详细地自定义自动并行化机制。更多信息请参阅 set_system 的描述。
最后,您可以使用参数 "thread_num" 和 "tsp_thread_num"(set_system)来影响自动并行化所使用的线程数。如果在程序中也执行手动并行化,减少线程数将非常有用。如果永久关闭自动并行化,也应关闭线程池,以节省操作系统资源。
HALCON 支持的所有图像采集设备均可在多核或多处理器硬件上使用。请注意,相应的算子都不会自动并行化。大多数算子都是可重入的,只有与设备连接相关的算子(open_framegrabber、info_framegrabber 和 close_framegrabber)是在其组中独占处理的,也就是说,它们会阻止其他图像采集算子的并发执行,但会与该组之外的所有非独占算子并行运行(参见 open_framegrabber)。此外,这些算子是本地的,也就是说,在 Windows 系统下,它们应由实例化相应对象的线程调用(参见 "仔细观察重入性" 一节 )。
默认情况下,HALCON 使用自旋锁来实现线程间的同步,以最大限度地提高性能。但是,有几种情况不建议使用自旋锁:
要关闭自旋锁,请在调用第一个 HALCON 算子之前调用函数 HSetUseSpinLock(0)。请注意,在 HALCON 初始化后调用 HSetUseSpinLock 会导致未定义的行为。
用于算子自动并行化的 HALCON 线程池将始终使用自旋锁,即使调用 HSetUseSpinLock 关闭了自旋锁。因此,必须确保线程池使用的线程数量不会超过实际可用的 CPUs 数量。如果您的程序使用任何形式的实时调度,您必须特别小心,否则您的程序可能会死锁。
HALCON 通常会在初始化过程中创建线程池。如果不需要线程池,可以在调用第一个 HALCON 算子之前调用函数 HSetStartUpThreadPool(0) 来阻止创建线程池。
在 Linux 系统中,线程继承创建线程的父线程的 CPU 亲和性。这意味着,如果启用了 HALCON 线程池,其线程将受到创建线程池时创建线程的线程激活的 CPU 亲和性掩模的限制。如果关闭了线程池,HALCON 的自动算子并行化功能将自动创建线程。这些线程将受限于调用 HALCON 算子并行化的线程的 CPU 亲和性掩码。
请注意,HALCON 在初始化过程中会查看进程的 CPU 亲和性掩模,以确定有多少 CPUs 可用于算子自动并行化。因此,如果随后更改 CPU 亲和性,HALCON 将不会注意到,并可能最终尝试使用比可用 CPUs 更多的 CPUs。在使用任何形式的实时调度时,这都会降低性能或导致死锁。如果用于初始化 HALCON 的线程使用了与其父进程不同的 CPU 亲和性掩模,也会出现问题,因为 HALCON 只考虑进程的 CPU 亲和性掩模。