numpy框架中的libblas系统库导致CPU sys高

背景

pre_image-pre-handle-worker服务会下载oss里的图片,然后再去计算图片hash,本来这种情况应该属于CPU us很高,优化前CPU sys很高,开6个进程,服务器的负载非常高,直接干满,截图如下所示:

排查

研发联系运维查看,运维根据之前的经验判断通过perf分析查看是CPU上下文切换、CPU等待调度导致的,但是无果,然后怀疑是否是磁盘IO、内网带宽满了导致的,当时和研发一直使用各种命令排查,strace、pidstat、iostat、dstat等,最后发现也不是磁盘IO导致的,也不是内网带宽不够导致的(32核的机器内网带宽峰值10G),这个时候就尴尬了,后来想到计算使用的框架使用的是numpy,然后怀疑是不是这个导致的,接着去github查看对应的issue,找到了一个issue(https://github.com/numpy/numpy/issues/8120),和咱们的情况类似,于是尝试用里面的方法试了下,果然好使,CPU sys使用率下降了

根本原因

numpy调用了这个系统库libblas,这个库直接开多线程运算的,libblas是一个c语言写的库,里面开的线程是真实的线程,默认libblas会使用总cpu核心数个线程,服务器是32核的,就会起32个线程,而pre_image-pre-handle-worker单个任务的计算时间不是很长,计算图片的平均时间是50~100ms,libblas把这50-100ms的任务拆成了很多个线程来完成,时间片是100ms,采用更多的线程反而增加了系统调度的负载,在竞争CPU的时候并没有真正运行,导致cpu将大量的时间耗费在寄存器、内核栈等资源的保存和恢复上,从而导致CPU sys高,CPU us低的现象,issue中也有句话 you are using openblas, it is expected that that will use all cpu cores and is super wasteful on small matrices.****You should be able to control it with the OPENBLAS_NUM_THREADS environment variable.

解决办法

在配置文件中配置OPENBLAS_NUM_THREADS=2,使用2个线程

[program:image-pre-handle-worker]
environment=PROJECT_NAME=image-pre-handle-worker,PROJECT_PORT=5000,OPENBLAS_NUM_THREADS=2
directory=/app/web/pre_image-pre-handle-worker/
command=/usr/bin/python3 /app/web/pre_image-pre-handle-worker/worker/image_prehandle_worker.py --port=%(process_num)02d
process_name=%(process_num)d
user=work
startretries=5
stopsignal=TERM
autorestart=true
stopasgroup=true
redirect_stderr=true
stdout_logfile=/data/log/supervisor/%(program_name)s-%(process_num)d.log
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=5
loglevel=info
numprocs = 20
numprocs_start=5000

优化后的 CPU sys使用率,计算速度较之前提升了1倍,现在开了20个进程,CPU使用率70%~80%

posted @ 2021-03-13 09:11  梦轻尘  阅读(332)  评论(0编辑  收藏  举报