1、背景介绍
在linux系统中可以使用isolcpus将操作系统和应用使用的核进行隔离,让操作系统只使用前两个核,具体做法是修改grub.cfg,在内核启动参数中增加
isolcpus=2,3,4,5,6,7,8,9,10,11,12,13
进行设置。?
但是设置完毕后发现无法使用openmp进行并行处理,运行测试程序后,用htop发现只能使用一个核运行。
当把grub.cfg中的isolcpus=2,3,4,5,6,7,8,9,10,11,12,13去掉后,即系统和应用不进行隔离,此时再运行openmp测试程序,发现是正常使用4个核,openmp能正确执行。
测试程序代码如下:
/*
============================================================================
Name : pthread_test.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <error.h>
#include <malloc.h>
#include <netdb.h>
#include <netinet/in.h>
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sched.h>
int hello1()
{
int iLoop =0;
int i = 0;
cpu_set_t cpu_info;
pthread_t xdma_t1[5];
pthread_attr_t attr1[5];
CPU_ZERO(&cpu_info);
for(i=3;i<8;i++)
{
CPU_SET(i,&cpu_info);
}
if( 0 != pthread_setaffinity_np(pthread_self(),sizeof(cpu_set_t),&cpu_info))
{
printf("11drvrecv:set affinity failed\n");
}
#pragma omp parallel num_threads(5)
{
}
while(1)
{
#pragma omp parallel for num_threads(5)
for(iLoop = 0;iLoop<=5;iLoop++)
{
;
}
}
return 0;
}
void main()
{
int ret = 0;
int i = 0;
cpu_set_t cpu_info;
pthread_t xdma_t1[5];
pthread_attr_t attr1[5];
if(0 != pthread_create(&xdma_t1,NULL,(void*)hello1,NULL) )
{
printf("FILE:%s LINE:%d FUNC: CmpDsPCtrl Error!\n",__FILE__,__LINE__);
return;
}
else
{
printf("%s %d Cmp: CmpDsPCtrl Started!\n",__FILE__,__LINE__);
}
while(1)
{
sleep(1);
}
return;
}
2、原因分析
在系统中使用了isolcpus会关闭对应的CPU核的migration,也就是run queue迁移,导致程序的线程不会迁移到空闲的核上。所以导致了openmp运行异常。
3、解决办法
查阅资料能发现可以使用OMP_PLACES来解决该问题,链接:https://www.openmp.org/spec-html/5.0/openmpse53.html?
具体做法是在/etc/environment中设置环境变量,改变openmp放线程的策略
OMP_PLACES=cores?
此时即使设置了isolcpus,也可以让openmp正确运行。
|