zoukankan      html  css  js  c++  java
  • SetThreadAffinityMask windows下绑定线程(进程)到指定的CPU核心

    原帖地址:https://www.cnblogs.com/lvdongjie/p/4476766.html

    一个程序指定到单独一个CPU上运行会比不指定CPU运行时快。这中间主要有两个原因:
    1)CPU切换时损耗的性能。
    2)Intel的自动降频技术和windows的机制冲突:windows有一个功能是平衡负载,可以将一个线程在不同时间分配到不同CPU,从而使得每一个CPU不“过累”。然而,Inter又有一个技术叫做SpeedStep,当一个CPU没有满负荷运行时自动降频从而达到节能减排的目的。这两个功能实际是冲突的:一个程序被分配到多个CPU协同工作->每个CPU都不是满载->每个CPU都会降频->windows发现每个CPU性能都降低了,因此程序执行速度也降低了。

    因此,将线程(进程)绑定到指定CPU核心,从而不让windows自作主张帮我们分散任务,从而提高单线程效率是很有必要的。有两种方法实现绑定进程到指定CPU:
    1)手工调节:在资源管理器的进程里面,设置相关性,可以设置进程到某个或者某些指定的CPU核心。
    手工指定CPU核心
    这种方法最简便,同样是最优效率的,因为你可以根据当前CPU的负载情况进行选择。
    2)代码自动调节:
    参考:http://www.cnblogs.com/kex1n/archive/2011/05/09/2040924.html
    具体函数为:

    1
    DWORD_PTR SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffinityMask);

    其中,第一个参数为线程句柄,第二个参数为一个mask。
    如果要知道当前线程的句柄,可以通过函数:GetCurrentThread()得到。否则,在创建多线程的时候,也同样可以得到创建的线程的句柄。
    第二个参数为mask,可取值为0~2^31(32位)和0~2^63(64位),每一位代表每一个CPU是否使用。
    比如,你要指定进程到第0个CPU上,则mask=0×01
    第1个CPU:mask=0×02
    第2个CPU:mask=0×04 (注意不是0×03)
    第3个CPU:mask=0×08
    以此类推。
    如果要指定多个CPU:
    比如第0、1个:mask=0×03
    第1、2个:mask=0×06
    以此类推。
    如果CPU个数不足,则会进行取模操作。比如一共4个CPU,则mask=0×0010则和0×01一样。
    这种方法的好处是多线程时不用每次都手动选择CPU,缺点是万一选到的CPU负载很高,那么程序执行速度就慢了(英雄所见略同所以大家都抢到同一个CPU去了么~~)
    效果如下图所示:
    指定CPU核心
    还有一个实用的函数来获取当前CPU的核心数量:

    1
    2
    3
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    printf("Number of processors: %d. ", info.dwNumberOfProcessors);

    输出的是逻辑核心数量,比如i3处理器就是双核心四线程,输出4。i5处理器是四核心四线程,输出也是4。
    这样就可以方便的知道当前系统一共有多少个CPU了,同时也方便了线程数选择。

    ===============================================================

    该函数中的h T h r e a d参数用于指明要限制哪个线程, dwThreadAffinityMask用于指明该线程能够在哪个CPU上运行。

    dwThreadAffinityMask必须是进程的亲缘性屏蔽的相应子集。返回值是线程的前一个亲缘性屏蔽。 

    因此,若要将3个线程限制到CPU1、2和3上去运行,可以这样操作: 

    //Thread 0 can only run on CPU 0.  
      
    SetThreadAffinityMask(hThread0, 0x00000001); //第0位是1  
      
    //Threads 1, 2, 3 run on CPUs 1, 2, 3.//第1 2 3位是1  
      
    SetThreadAffinityMask(hThread1, 0x00000002);  
      
    SetThreadAffinityMask(hThread2, 0x00000003);  
      
    SetThreadAffinityMask(hThread3, 0x00000004); 

    参考地址:https://blog.csdn.net/johnny710vip/article/details/23708241

  • 相关阅读:
    社交需求和社交产品的更替
    腾讯产培生面经
    【C++基础】类class
    【C++基础】结构struct
    【C++基础】C-串知识整理
    GeoServer war包在tomcat7中配置遇到的一个问题
    pgrouting 2.0 的环境配置
    阿里2014年9月笔试中的一个算法设计题--擦黑板剩余数字
    VisualSVN Server的启动关闭脚本
    二叉树遍历(前序、中序、后序)的递归及非递归实现(小结)
  • 原文地址:https://www.cnblogs.com/wainiwann/p/11466409.html
Copyright © 2011-2022 走看看