HPC 调试经验:线程亲和性设置失败

孔杰 山东科技大学计算机学院CogTwins Lab(Cognitive Industrial Digital Twins Lab | Official web of Cognitive Industrial Digital Twins Lab team)   

在高性能计算 (HPC) 环境下,我们经常需要结合 CPU 和 GPU 等多种硬件加速器协同工作。以下分享对于ONNX Runtime 在推理时出现线程亲和性设置错误的实际问题及解决思路:在讲解过程中,我们会介绍相关技术背景(如线程亲和性、ROCm、LD_LIBRARY_PATH 等),帮助初学者理解整个排查流程。

线程亲和性设置失败

在进行模型推理时,出现如下错误日志:

2023-05-18 08:24:58.694 [E:onnxruntime:Default, env.cc:251] 
pthread_setaffinity_np failed for thread: 531, index: 6, mask: {7, 39, }, 
error code: 22 error msg: Invalid argument. Specify the number of threads explicitly so the affinity is not set.

线程亲和性是什么?

线程亲和性(Thread Affinity)是指将线程绑定到特定 CPU 核上运行,以尽量让线程在同一个或同一组处理器核上执行,从而提高缓存利用率和性能。例如,Linux 默认会让线程倾向于“绑”在上次运行过的 CPU 核上,以减少缓存丢失。但是有时应用需要手动绑定线程到指定核上,这就称为“硬”亲和性。在此错误中,ONNX Runtime 在后台尝试为每个线程绑定亲和性时失败了。

错误原因分析

错误信息中提示 Invalid argument. Specify the number of threads explicitly so the affinity is not set.,意思是未显式指定线程数,导致尝试设置亲和性时出错。一旦我们没有显式设置线程数量,ONNX Runtime 默认会为每个物理核心创建线程池并设置亲和性。如果某些 CPU 核不可用或参数不符,就会触发 pthread_setaffinity_np 返回 22(无效参数)。简单来说,这是 ONNX Runtime 在多核系统中自动分配线程发生的一个提示:告诉我们应该手动指定线程数,避免自动亲和性设置。

解决方案

可以通过显式设置线程数来避免亲和性问题,具体有以下几种方法:

  • 在代码中指定线程数:创建 SessionOptions 时,设置 inter_op_num_threads(操作之间并行线程)和 intra_op_num_threads(单次操作内部并行线程)为合适的值。显式设置线程总数后,ONNX Runtime 将不再自动设置亲和性。例如,如果机器上有 4 个核,可以这样设置:

    import onnxruntime as ort
    sess_opts = ort.SessionOptions()
    sess_opts.inter_op_num_threads = 4   # 操作之间并行线程数
    sess_opts.intra_op_num_threads = 4   # 操作内部并行线程数
    session = ort.InferenceSession('model.onnx', sess_opts)
    # 显式设置后,错误提示会消失,并且性能在合理使用核数时能得到保证。
    
  • 设置环境变量:可以通过设置 OpenMP 环境变量 OMP_NUM_THREADS 来影响线程数(ONNX Runtime 会参考该变量)。例如,在 Linux 环境下:

    # 设置 OMP_NUM_THREADS 环境变量
    export OMP_NUM_THREADS=4
    
  • 调整容器配置:在本次问题中,我们在重建容器时显式指定使用4 张异构加速卡(例如 4 张不同型号的 GPU)并设置相应的线程数,使得推理时每个加速卡对应的线程数明确,避免了自动亲和性设置引发的问题。

通过上述方法显式指定线程数量后,再次运行推理脚本,线程亲和性错误即解决。需要注意的是,这个错误本身并不一定会导致推理失败(通常只是警告),但为了日志清晰和预防潜在性能问题,建议按照以上方法明确线程数。

总结

  • 线程亲和性(CPU 亲和性)是将线程绑定到特定 CPU 核的机制,有助于提高缓存命中率。如果 ONNX Runtime 报错线程亲和性失败(error code 22),通常只需显式指定线程数(如设置 intra_op_num_threads / inter_op_num_threadsOMP_NUM_THREADS),这样就不会自动设置亲和性。

  • 在 HPC 开发中,遇到报错要先看日志、定位根因:对照错误信息中的关键字(如 affinitySegmentation fault),结合系统环境(多核配置、GPU 驱动等)分析原因,并尝试调整环境变量或程序配置来解决。以上经验可供其他初学者参考和借鉴。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值