`

Linux中线程与CPU核的绑定

阅读更多
最近在对项目进行性能优化,由于在多核平台上,所以了解了些进程、线程绑定cpu核的问题,在这里将所学记录一下。
    不管是线程还是进程,都是通过设置亲和性(affinity)来达到目的。对于进程的情况,一般是使用sched_setaffinity这个函数来实现,网上讲的也比较多,这里主要讲一下线程的情况。
    与进程的情况相似,线程亲和性的设置和获取主要通过下面两个函数来实现:
    int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
const cpu_set_t *cpuset);
    int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize,
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中调度。      
      以下为测试代码:
点击(此处)折叠或打开
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

void *myfun(void *arg)
{
    cpu_set_t mask;
    cpu_set_t get;
    char buf[256];
    int i;
    int j;
    int num = sysconf(_SC_NPROCESSORS_CONF);
    printf("system has %d processor(s)\n", num);

    for (i = 0; i < num; i++) {
        CPU_ZERO(&mask);
        CPU_SET(i, &mask);
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
            fprintf(stderr, "set thread affinity failed\n");
        }
        CPU_ZERO(&get);
        if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
            fprintf(stderr, "get thread affinity failed\n");
        }
        for (j = 0; j < num; j++) {
            if (CPU_ISSET(j, &get)) {
                printf("thread %d is running in processor %d\n", (int)pthread_self(), j);
            }
        }
        j = 0;
        while (j++ < 100000000) {
            memset(buf, 0, sizeof(buf));
        }
    }
    pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
    pthread_t tid;
    if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0) {
        fprintf(stderr, "thread create failed\n");
        return -1;
    }
    pthread_join(tid, NULL);
    return 0;
}
       这段代码将使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核,减少进程、线程的核间切换,有可能可以获得更高的性能。
------------------------------2---------------------------------------

在服务器上,我们经常会有多个CPU的情况,而此时如果把进程都绑定在一个CPU上,那么对资源太多浪费了,下面的代码就实现了如何将程序绑定在不同的cpu上。传入参数代表绑定第几个cpu(从0开始计算)

//cpu_test.cpp
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>
//#define __USE_GNU
#include<sched.h>
#include<ctype.h>
#include<string.h>
int main(int argc, char* argv[])
{
        int num = sysconf(_SC_NPROCESSORS_CONF);
        int created_thread = 0;
        int myid;
        int i;
        int j = 0;
        cpu_set_t mask;
        cpu_set_t get;
        if (argc != 2)
        {
                printf(“usage : ./cpu num\n”);
                exit(1);
        }
        myid = atoi(argv[1]);
        printf(“system has %i processor(s). \n”, num);
        CPU_ZERO(&mask);
        CPU_SET(myid, &mask);
        if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
        {
                printf(“warning: could not set CPU affinity, continuing…\n”);
        }
        while (1)
        {
    usleep(10000);
                CPU_ZERO(&get);
                if (sched_getaffinity(0, sizeof(get), &get) == -1)
                {
                        printf(“warning: cound not get cpu affinity, continuing…\n”);
                }
                for (i = 0; i < num; i++)
                {
                        if (CPU_ISSET(i, &get))
                        {
                                printf(“this process %d is running processor : %d\n”,getpid(), i);
                        }
                }
        }
        return 0;
}
//g++ cpu_test.cpp -o cpu_test
分享到:
评论

相关推荐

    多核线程绑定

    创建一个线程,并将该线程绑定到多核cpu中,不占用主线程的资源,这样可以在所开的线程中做一些动作,不会影响主线程中的动作。应用:客户将所有的刷新动作交给主线程完成时,可能拖动鼠标,窗口均在不断的刷新,CPU...

    threadBandCpu:将java线程绑定到具体的cpu上执行

    threadBandCpu将java线程绑定到具体的cpu上执行环境:Ubuntu 12.04具体介绍请移步这里:如何使用?调用ThreadBandCpu.bandCpu并实现Runnable的run方法,第二个参数的意思是在第几个cpu上执行假如有4个cpu,那么就是 ...

    linux 系统性能相关1.rar

     Linux 线程库性能测试与分析; 网卡软中断不能分发到CPU多核 问题的说明; Linux的实时性能测试.pdf  多核处理器上,怎样将软中断,内核线程绑定在指定的core上; LINUX上中断在各个CPU之间的负载平衡问题; 网卡...

    Linux系统故障诊断与排除--James Kirkland

    8.2 Linux线程 174 8.3 确定进程挂起 180 8.4 进程核心 186 8.4.1 信号 187 8.4.2 限制 189 8.4.3 核心文件 191 8.5 小结 192 第9章 备份与恢复 194 9.1 备份介质 194 9.1.1 磁带 195 9.1.2 ...

    基于opencv和多线程的别踩白块儿游戏辅助.zip

    丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG...

    基于pyqt5和opencv的多线程图像(视频)处理.zip

    丰富的功能:库中包含了数千个优化过的函数,涵盖了计算机视觉领域的诸多方面,如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG...

    cmd操作命令和linux命令大全收集

    mem 查看cpu使用情况 attrib 文件名(目录名) 查看某文件(目录)的属性 attrib 文件名 -A -R -S -H 或 +A +R +S +H 去掉(添加)某文件的 存档,只读,系统,隐藏 属性;用+则是添加为某属性 dir 查看文件,...

    multi-thread.rar_Linux/Unix编程_C/C++_

    实现了一个将线程与具体的CPU绑定的例子

    PHP扩展php-affinity.zip

    一般在如下场景我们可能会希望修改进程的cpu亲和性: 频繁的并行运算 线程可伸缩性测试(通过增加cpu核心数量模拟线性扩展) 运行时间敏感的,决定性的进程向nginx,swoole等开源软件,都提供了设置cpu亲和性的...

    C语言实现的支持高并发、超高性能Web服务器源码.rar

    * 支持工作进程绑定CPU * 支持进程 崩溃后自动重启安全机制: * HTTP请求报文合法性校验 * 活跃超时控制(防止僵尸连接)和累积超时控制(防止慢速攻击) * 每个IP连接数 限制 * 全局最大连接数限制 * 最大单个...

    weave:最新的多线程运行时

    它已针对以下CPU体系结构在Linux,MacOS和Windows上进行了持续测试:x86,x86_64和带有C和C ++后端的ARM64。 Weave旨在提供一种可组合的,高性能,超低开销和细粒度的并行运行时,使开发人员摆脱以下常见的烦恼:...

    C/C++笔试题(附答案,华为面试题系列)

    3.多CPU系统中,使用线程提高CPU利用率 4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独 立的运行部分,这样的程序会利于理解和修改。 其他情况都使用单线程。 11.Windows是内核...

    Intel TBB Library

    TBB,Thread Building Blocks,线程构建模块,是Intel公司开发的并行编程开发的工具。 OSCON 上,Intel 宣布,Threading Building Blocks,Intel 众多软件开发工具中的一个,open source了。协议是 GPLv2。 TBB 获得过...

    intel的tbb库,版本是2018 update5

    TBB,Thread Building Blocks,线程构建模块,是Intel公司开发的并行编程开发的工具。 OSCON 上,Intel 宣布,Threading Building Blocks,Intel 众多软件开发工具中的一个,open source了。协议是 GPLv2。 TBB 获得过...

    tbb2019_20190522oss_win.zip

    TBB,Thread Building Blocks,线程构建模块,是Intel公司开发的并行编程开发的工具。 OSCON 上,Intel 宣布,Threading Building Blocks,Intel 众多软件开发工具中的一个,open source了。协议是 GPLv2。 TBB 获得过...

    terarkdb:与RocksDB兼容的KV存储引擎,性能更高

    绩效概述RocksDB v6.12 服务器英特尔:registered:至强:registered:金牌5218 CPU @ 2.30GHz(2插槽,32核64线程) 376 GB DRAM NVMe TLC固态硬盘(3.5 TB) 台式工具和工作量使用db_bench 10个客户端线程,每个线程20...

    polylidar:Polylidar3D-从3D数据中快速提取多边形

    •••••主要特征从多个2D和3D数据源中快速(多)多边形提取用C ++编写以实现可移植性极快的单线程,但包括使用数据和基于任务的并行性的CPU多线程可能会返回带Kong的多边形使用PyBind11的Python3绑定调用python /...

    statsd-proxy:用于etsystatsd的快速一致哈希代理

    我们尝试在原始的nodejs代理上使用SO_REUSEPORT ,这使我们能够在单个端口上绑定多个udp套接字,但是nodejs(或libuv)已禁用此选项,而golang则没有方法setsockopt() 。 因此,我们在C语言中做到了。 特征 零依赖...

    易语言程序免安装版下载

    操作系统界面功能支持库(shell.fne)中的“执行()”命令增加一个参数“窗口显示方式”,作用与核心库“运行()”命令的同名参数一致。 6. 数据库操作支持库增加读写长整数字段的功能,但受限于系统接口暂不能读写...

    新版Android开发教程.rar

    � 采用了对有限内存、电池和 CPU 优化过的虚拟机 Dalvik , Android 的运行速度比想象的要快很多。 � 运营商(中国移动等)的大力支持,产业链条的热捧。 � 良好的盈利模式( 3/7 开),产业链条的各方:运营商、...

Global site tag (gtag.js) - Google Analytics