Linux中線程與CPU核的綁定

  

  最近在進行性能優化需要了解了些進程、線程綁定cpu核的問題。

    不管是線程還是進程,都是通過設置親和性(affinity)來達到目的。對於進程的情況,一般是使用sched_setaffinity這個函數來實現,網上講的也比較多,這裏主要講一下線程的情況。
    與進程的情況相似,線程親和性的設置和獲取主要通過下面兩個函數來實現:
int pthread_setaffinity_np(pthread_tthread, size_tcpusetsize,
const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_tthread, size_tcpusetsize, 
cpu_set_t *cpuset);
    從函數名以及參數名都很明瞭,唯一需要點解釋下的可能就是cpu_set_t這個結構體了。這個結構體的理解類似於select中的fd_set,可以理解爲cpu集,也是通過約定好的宏來進行清除、設置以及判斷:
//初始化,設爲空
      void CPU_ZERO (cpu_set_t *set); 
      //將某個cpu加入cpu集中 
       void CPU_SET (int cpu, cpu_set_t *set); 
       //將某個cpu從cpu集中移出 
       void CPU_CLR (int cpu, cpu_set_t *set); 
       //判斷某個cpu是否已在cpu集中設置了 
       int CPU_ISSET (int cpu, const cpu_set_t *set); 
       cpu集可以認爲是一個掩碼,每個設置的位都對應一個可以合法調度的 cpu,而未設置的位對應一個不可調度的 CPU。換而言之,線程都被綁定了,只能在那些對應位被設置了的處理器上運行。通常,掩碼中的所有位都被置位了,也就是可以在所有的cpu中調度。       
      以下爲測試代碼:

點擊(此處)摺疊或打開

  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <pthread.h>
  7. #include <sched.h>

  8. void *myfun(void*arg)
  9. {
  10.     cpu_set_t mask;
  11.     cpu_set_t get;
  12.     char buf[256];
  13.     int i;
  14.     int j;
  15.     int num= sysconf(_SC_NPROCESSORS_CONF);
  16.     printf("system has %d processor(s)\n", num);

  17.     for(i= 0; i< num; i++){
  18.         CPU_ZERO(&mask);
  19.         CPU_SET(i,&mask);
  20.         if(pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask)< 0){
  21.             fprintf(stderr,"set thread affinity failed\n");
  22.         }
  23.         CPU_ZERO(&get);
  24.         if(pthread_getaffinity_np(pthread_self(), sizeof(get),&get)< 0){
  25.             fprintf(stderr,"get thread affinity failed\n");
  26.         }
  27.         for(j= 0; j< num; j++){
  28.             if(CPU_ISSET(j,&get)){
  29.                 printf("thread %d is running in processor %d\n",(int)pthread_self(), j);
  30.             }
  31.         }
  32.         j = 0;
  33.         while(j++< 100000000){
  34.             memset(buf, 0, sizeof(buf));
  35.         }
  36.     }
  37.     pthread_exit(NULL);
  38. }

  39. int main(int argc, char*argv[])
  40. {
  41.     pthread_t tid;
  42.     if(pthread_create(&tid,NULL,(void*)myfun,NULL)!= 0){
  43.         fprintf(stderr,"thread create failed\n");
  44.         return -1;
  45.     }
  46.     pthread_join(tid,NULL);
  47.     return 0;
  48. }
       這段代碼將使myfun線程在所有cpu中依次執行一段時間,在我的四核cpu上,執行結果爲  :
       system has 4 processor(s)        
       thread 1095604544 is running in processor 0        
       thread 1095604544 is running in processor 1        
       thread 1095604544 is running in processor 2        
       thread 1095604544 is running in processor 3 
       在一些嵌入式設備中,運行的進程線程比較單一,如果指定進程線程運行於特定的cpu核,減少進程、線程的核間切換,有可能可以獲得更高的性能。

轉載處:http://blog.chinaunix.net/uid-27714502-id-3515874.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章