• 正文
    • 基本概念
    • 代碼綁定實現(xiàn)
    • 代碼綁定查看
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

Linux 中用c++實現(xiàn)線程綁定CPU

03/13 09:58
1827
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

嵌入式里面我們會使用到多核的cpu,隨著產(chǎn)品芯片性能提升,我們也會有很多功能,以及很多進程產(chǎn)生運行,這個時候我們在任務(wù)調(diào)度調(diào)優(yōu)的時候,把一些進程綁定到固定cpu運行,下面就來分享一下cpu綁定運行的過程:

首先運行的環(huán)境需要多核,大家可以按照下面命令進行查詢對應(yīng)設(shè)備的cpu數(shù)量

查看cpu有幾個核

使用cat /proc/cpuinfo查看cpu信息,如下兩個信息:

processor,指明第幾個cpu處理器
cpu cores,指明每個處理器的核心數(shù)

基本概念

cpu親和性(affinity)

CPU的親和性, 就是進程要在指定的 CPU 上盡量長時間地運行而不被遷移到其他處理器,也稱為CPU關(guān)聯(lián)性;再簡單的點的描述就將指定的進程或線程綁定到相應(yīng)的cpu上;在多核運行的機器上,每個CPU本身自己會有緩存,緩存著進程使用的信息,而進程可能會被OS調(diào)度到其他CPU上,如此,CPU cache命中率就低了,當綁定CPU后,程序就會一直在指定的cpu跑,不會由操作系統(tǒng)調(diào)度到其他CPU上,性能有一定的提高。

軟親和性(affinity)

就是進程要在指定的 CPU 上盡量長時間地運行而不被遷移到其他處理器,Linux 內(nèi)核進程調(diào)度器天生就具有被稱為 軟 CPU 親和性(affinity) 的特性,這意味著進程通常不會在處理器之間頻繁遷移。這種狀態(tài)正是我們希望的,因為進程遷移的頻率小就意味著產(chǎn)生的負載小。

硬親和性(affinity)

簡單來說就是利用linux內(nèi)核提供給用戶的API,強行將進程或者線程綁定到某一個指定的cpu核運行。

代碼綁定實現(xiàn)

上面我們使用cat /proc/cpuinfo命令查詢了自己設(shè)備的CPU,以我為例,我的電腦從0~7一共有8核。

下面是代碼的demo:

#include <stdio.h>
#include <unistd.h>
#include <thread>

void thread_func1()
{
        cpu_set_t mask;
        CPU_ZERO(&mask);
        CPU_SET(1, &mask); //指定該線程使用的CPU
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
                perror("pthread_setaffinity_np");
        }
        int count = 0;
        while(1)
        {
                count ++;
                sleep(1);
                printf("fun 1 cnt :%d n",count);
                for(int i = 0; i < 8; i++) {
                        if (CPU_ISSET(i, &mask))  //查看cpu i 是否在get 集合當中
                        {
                                printf("1 this process %d of running processor: %dn", getpid(), i);
                        }
                }
        }
}

void thread_func2()
{
        int count = 0;
        cpu_set_t mask;
        CPU_ZERO(&mask);
        CPU_SET(5, &mask);
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
                perror("pthread_setaffinity_np");
        }
        while(1)
        {
                usleep(1000*1000);
                count ++;
                printf("fun 2 cnt :%d n",count);
                for(int i = 0; i < 8; i++) {
                 if (CPU_ISSET(i, &mask))  //查看cpu i 是否在get 集合當中
                {
                       printf("2 this process %d of running processor: %dn", getpid(), i);

                    }
                }

        }

}

int main(int argc, char *argv[])
{
      int cpus = 0;

        cpus = sysconf(_SC_NPROCESSORS_CONF);

        printf("cpus: %dn", cpus); //查看cpu的個數(shù);


    cpu_set_t mask;
    CPU_ZERO(&mask);
    CPU_SET(7, &mask);
    if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
        perror("sched_setaffinity");
    }

    std::thread t1(thread_func1);
    std::thread t2(thread_func2);
        usleep(1000); /* 讓當前的設(shè)置有足夠時間生效*/
       while(1)
        {
                /*查看運行在當前進程的cpu*/
                sleep(1); /* 讓當前的設(shè)置有足夠時間生效*/
                printf("fun main n");
                for(int i = 0; i < cpus; i++) {

                        if (CPU_ISSET(i, &mask))  //查看cpu i 是否在get 集合當中
                        {
                                printf("3 this process %d of running processor: %dn", getpid(), i);

                        }
                }
        }

    
    t1.join();
    t2.join();
}

使用此命令編譯:

g++ test_select_cpu.cpp -pthread --std=c++11

上面一共運行了三個線程,一個是main 主線程,還有兩個是自己定義的thread。

最重要的設(shè)置代碼就是下面所示:設(shè)置cpu 親和

cpu_set_t mask;
CPU_ZERO(&mask);/* 初始化set集,將set置為空*/
CPU_SET(5, &mask);/* 將對應(yīng)的cpu序號加入到集合*/
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) /*設(shè)置cpu 親和性(affinity)*/
{ 
    perror("pthread_setaffinity_np");
}

執(zhí)行代碼?./a.out

代碼綁定查看

使用ps -ef | grep a.out?命令查看對應(yīng)的PID

使用 top命令查看對應(yīng)pid的線程詳細信息?top -p 54056

在進入top命令后,繼續(xù)輸入?f

使用上下?移動高亮到p

空格?選中

再按q?退出顯示

輸入大寫H

就可以看到對應(yīng)線程數(shù)據(jù)了

最右邊就是對應(yīng)的線程綁定的CPU序號。

作者:良知猶存,白天努力工作,晚上原創(chuàng)公號號主。公眾號內(nèi)容除了技術(shù)還有些人生感悟,一個認真輸出內(nèi)容的職場老司機,也是一個技術(shù)之外豐富生活的人,攝影、音樂 and 籃球。關(guān)注我,與我一起同行。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

一個程序員,喜歡寫文章,還喜歡打籃球,也喜歡吉他鋼琴的駁雜之人。日常更新自己,分享包括但不限于C/C++、嵌入式、物聯(lián)網(wǎng)、Linux等編程學習筆記,同時,公眾號內(nèi)包含大量的學習資源。歡迎關(guān)注,一同交流學習,共同進步!