管理处理器的亲和性(affinity)

转自: http://www.ibm.com/developerworks/cn/linux/l-affinity.html

简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。

2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现 硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。

什么是 Linux 内核硬亲和性(affinity)?

在 Linux 内核中,所有的进程都有一个相关的数据结构,称为 task_struct。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是 cpus_allowed 位掩码。这个位掩码由 n 位组成,与系统中的 n 个逻辑处理器一一对应。 具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。

如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。

Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:

  • sched_set_affinity() (用来修改位掩码)
  • sched_get_affinity() (用来查看当前的位掩码)

注意,cpu_affinity 会被传递给子线程,因此应该适当地调用 sched_set_affinity

为什么应该使用硬亲和性(affinity)?

通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU 之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。

一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。

原因 1. 有大量计算要做

基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。

原因 2. 您在测试复杂的应用程序

测试复杂软件是我们对内核的亲和性(affinity)技术感兴趣的另外一个原因。考虑一个需要进行线性可伸缩性测试的应用程序。有些产品声明可以在 使用更多硬件 时执行得更好。

我们不用购买多台机器(为每种处理器配置都购买一台机器),而是可以:

  • 购买一台多处理器的机器
  • 不断增加分配的处理器
  • 测量每秒的事务数
  • 评估结果的可伸缩性

如果应用程序随着 CPU 的增加可以线性地伸缩,那么每秒事务数和 CPU 个数之间应该会是线性的关系(例如斜线图 —— 请参阅下一节的内容)。这样建模可以确定应用程序是否可以有效地使用底层硬件。

Amdahl 法则

Amdahl 法则是有关使用并行处理器来解决问题相对于只使用一个串行处理器来解决问题的加速比的法则。加速比(Speedup) 等于串行执行(只使用一个处理器)的时间除以程序并行执行(使用多个处理器)的时间:

 

      T(1)
S = ------T(j)

 

其中 T(j) 是在使用 j 个处理器执行程序时所花费的时间。

Amdahl 法则说明这种加速比在现实中可能并不会发生,但是可以非常接近于该值。对于通常情况来说,我们可以推论出每个程序都有一些串行的组件。随着问题集不断变大,串行组件最终会在优化解决方案时间方面达到一个上限。

Amdahl 法则在希望保持高 CPU 缓存命中率时尤其重要。如果一个给定的进程迁移到其他地方去了,那么它就失去了利用 CPU 缓存的优势。实际上,如果正在使用的 CPU 需要为自己缓存一些特殊的数据,那么所有其他 CPU 都会使这些数据在自己的缓存中失效。

因此,如果有多个线程都需要相同的数据,那么将这些线程绑定到一个特定的 CPU 上是非常有意义的,这样就确保它们可以访问相同的缓存数据(或者至少可以提高缓存的命中率)。否则,这些线程可能会在不同的 CPU 上执行,这样会频繁地使其他缓存项失效。

原因 3. 您正在运行时间敏感的、决定性的进程

我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。

下面的样例应用程序显示了这是如何工作的。

如何利用硬亲和性(affinity)

现在让我们来设计一个程序,它可以让 Linux 系统非常繁忙。可以使用前面介绍的系统调用和另外一些用来说明系统中有多少处理器的 API 来构建这个应用程序。实际上,我们的目标是编写这样一个程序:它可以让系统中的每个处理器都繁忙几秒钟。可以从后面的“下载”一节中 下载样例程序。


清单 1. 让处理器繁忙

                
/* This method will create threads, then bind each to its own cpu. */
bool do_cpu_stress(int numthreads)
{int ret = TRUE;int created_thread = 0;/* We need a thread for each cpu we have... */while ( created_thread < numthreads - 1 ){int mypid = fork();if (mypid == 0) /* Child process */{printf("\tCreating Child Thread: #%i\n", created_thread);break;}else /* Only parent executes this */{/* Continue looping until we spawned enough threads! */ ;created_thread++;}}/* NOTE: All threads execute code from here down! */

 

正如您可以看到的一样,这段代码只是通过 fork 调用简单地创建一组线程。每个线程都执行这个方法中后面的代码。现在我们让每个线程都将亲和性(affinity)设置为自己的 CPU。


清单 2. 为每个线程设置 CPU 亲和性(affinity)

                cpu_set_t mask;/* CPU_ZERO initializes all the bits in the mask to zero. */CPU_ZERO( &mask );/* CPU_SET sets only the bit corresponding to cpu. */CPU_SET( created_thread, &mask );/* sched_setaffinity returns 0 in success */if( sched_setaffinity( 0, sizeof(mask), &mask ) == -1 ){printf("WARNING: Could not set CPU Affinity, continuing...\n");}

 

如果程序可以执行到这儿,那么我们的线程就已经设置了自己的亲和性(affinity)。调用 sched_setaffinity 会设置由 pid 所引用的进程的 CPU 亲和性(affinity)掩码。如果 pid 为 0,那么就使用当前进程。

亲和性(affinity)掩码是使用在 mask 中存储的位掩码来表示的。最低位对应于系统中的第一个逻辑处理器,而最高位则对应于系统中最后一个逻辑处理器。

每个设置的位都对应一个可以合法调度的 CPU,而未设置的位则对应一个不可调度的 CPU。换而言之,进程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了。这些线程的亲和性(affinity)都会传递给从它们派生的子进程中。

注意不应该直接修改位掩码。应该使用下面的宏。虽然在我们的例子中并没有全部使用这些宏,但是在本文中还是详细列出了这些宏,您在自己的程序中可能需要这些宏。


清单 3. 间接修改位掩码的宏

                
void CPU_ZERO (cpu_set_t *set)
这个宏对 CPU 集 set 进行初始化,将其设置为空集。
void CPU_SET (int cpu, cpu_set_t *set)
这个宏将 cpu 加入 CPU 集 set 中。
void CPU_CLR (int cpu, cpu_set_t *set)
这个宏将 cpu 从 CPU 集 set 中删除。
int CPU_ISSET (int cpu, const cpu_set_t *set)
如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。

 

对于本文来说,样例代码会继续让每个线程都执行某些计算量较大的操作。


清单 4. 每个线程都执行一个计算敏感的操作

                /* Now we have a single thread bound to each cpu on the system */int computation_res = do_cpu_expensive_op(41);cpu_set_t mycpuid;sched_getaffinity(0, sizeof(mycpuid), &mycpuid);if ( check_cpu_expensive_op(computation_res) ){printf("SUCCESS: Thread completed, and PASSED integrity check!\n",mycpuid);ret = TRUE;}else{printf("FAILURE: Thread failed integrity check!\n",mycpuid);ret = FALSE;}return ret;
}

 

现在您已经了解了在 Linux 2.6 版本的内核中设置 CPU 亲和性(affinity)的基本知识。接下来,我们使用一个 main 程序来封装这些方法,它使用一个用户指定的参数来说明要让多少个 CPU 繁忙。我们可以使用另外一个方法来确定系统中有多少个处理器:

int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF);

这个方法让程序能够自己确定要让多少个处理器保持繁忙,例如缺省让所有的处理器都处于繁忙状态,并允许用户指定系统中实际处理器范围的一个子集。

运行样例程序

当运行前面介绍的 样例程序 时,可以使用很多工具来查看 CPU 是否是繁忙的。如果只是简单地进行测试,可以使用 Linux 命令top。在运行 top 命令时按下 “1” 键,可以看到每个 CPU 执行进程所占用的百分比。

结束语

这个样例程序虽然非常简单,但是它却展示了使用 Linux 内核中实现的硬亲和性(affinity)的基本知识。(任何使用这段代码的应用程序都无疑会做一些更有意义的事情。)了解了 CPU 亲和性(affinity)内核 API 的基本知识,您就可以从复杂的应用程序中榨取出最后一点儿性能了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

流水线乘法器

流水线乘法器 题目描述 实现4bit无符号数流水线乘法器设计。 电路的接口如下图所示。 将乘法分解为若干个加法。 `timescale 1ns/1nsmodule multi_pipe#(parameter size = 4 )(input clk , input rst_n ,input [size-1:0] mul_a ,input [size-1:0] …

贷款审批时,会重点看征信报告哪些内容?

大家都知道申请贷款需要提供个人征信报告&#xff0c;但是大家知道贷款公司是怎么看征信报告的吗&#xff1f;哪些内容是信贷公司重点审核的对象呢&#xff1f;一、征信报告记录时间一般信贷公司会重点考察借款人最近两年内的征信情况。二、征信报告打印时间征信报告的打印时间…

什么叫白户,白户能贷款吗?

前几天有一个朋友跟贷款教授反映&#xff0c;他从来没有过信用逾期记录&#xff0c;但是申请贷款的时候被贷款机构告知&#xff0c;他是“征信白户”&#xff0c;所以做不了。相信有不少朋友都会遇到过类似的情况&#xff0c;那征信白户到底是什么意思&#xff0c;为什么征信白…

简易交通灯

简易交通灯 题目描述 要求实现一个交通红绿灯,具有红黄绿三个小指示灯和一个行人按钮,正常情况下,机动车道指示灯按照60时钟周期绿灯,5个时钟周期黄灯,10个时钟周期红灯循环。当行人按钮按下,如果剩余绿灯时间大于10个时钟,则缩短为10个时钟,小于10个时钟则保持不变。…

如何使用oprofile对软件做profiling

排行榜 收藏 打印 发给朋友 举报发布者&#xff1a;jackzhang热度112票 浏览1257次 【共0条评论】【我要评论】时间&#xff1a;2014年1月08日 11:04关于Xilinx Zynq-7000带来的新的系统设计思路&#xff0c;以及Profiling的对象libjpeg&#xff0c;前文已经描述过了&#xff…

5种常见信用卡还款方式对比

信用卡还款&#xff0c;你经常使用哪种方式呢&#xff1f;下面我们来对比下常用几种信用卡还款方式的优劣。1、自动还款&#xff1a;自动还款就是开通自动还款功能&#xff0c;绑定本行的储蓄卡账号&#xff0c;还款日到期了自动扣款。优势&#xff1a;可以及时还款&#xff0c…

网上贷款,靠谱吗?

随着互联网技术的发展&#xff0c;通过网上贷款的人越来越多&#xff0c;但也有很多网友对网上贷款表示质疑&#xff0c;认为网上贷款不靠谱&#xff0c;那到底网上贷款靠不靠谱呢&#xff1f;首先我想说的&#xff0c;网上贷款有真实的&#xff0c;也有虚假的&#xff0c;靠不…

Julia与R/Python/MATLAB比较及Julia中的Text Analysis模块

http://site.douban.com/146782/widget/notes/15468638/note/356127615/ 上午等着R跑数&#xff0c;R是出了名的慢&#xff0c;特别是处理文本时。无聊中&#xff0c;刷了一遍微博&#xff0c;惊现R界的扫地僧&#xff08;谢益辉语&#xff09;宫雨放出了RJulia。GitHub地址在此…

根据RTL图编写Verilog程序

根据RTL图编写Verilog程序 题目描述 根据以下RTL图&#xff0c;使用 Verilog HDL语言编写代码&#xff0c;实现相同的功能&#xff0c;并编写testbench验证功能。 timescale 1ns/1nsmodule RTL(input clk,input rst_n,input data_in,output reg data_out);reg data_in_reg;a…

Chapter 5:Spectral-Subtractive Algorithms

作者&#xff1a;桂。 时间&#xff1a;2017-05-24 10:06:39 主要是《Speech enhancement: theory and practice》的读书笔记&#xff0c;全部内容可以点击这里。 书中代码&#xff1a;http://pan.baidu.com/s/1hsj4Wlu&#xff0c;提取密码&#xff1a;9dmi 一、谱减的基本原…

Chapter 7:Statistical-Model-Based Methods

作者&#xff1a;桂。 时间&#xff1a;2017-05-25 10:14:21 主要是《Speech enhancement: theory and practice》的读书笔记&#xff0c;全部内容可以点击这里。 书中代码&#xff1a;http://pan.baidu.com/s/1hsj4Wlu&#xff0c;提取密码&#xff1a;9dmi 前言 最近学习有一…

使用握手信号实现跨时钟域数据传输

使用握手信号实现跨时钟域数据传输 题目描述 分别编写一个数据发送模块和一个数据接收模块,模块的时钟信号分别为clk_a,clk_b。两个时钟的频率不相同。数据发送模块循环发送0-7,在每个数据传输完成之后,间隔5个时钟,发送下一个数据。请在两个模块之间添加必要的握手信号,…

如何学好C++

作者&#xff1a;陈皓 出处&#xff1a;http://goo.gl/43XkL 昨天写了一篇如何学好C语言&#xff0c;就有人回复问我如何学好C&#xff0c;所以&#xff0c;我把我个人的一些学习经验写在这里&#xff0c;希望对大家有用。首先&#xff0c;因为如何学好C语言中谈到了算法和系统…

单边谱 → 双边谱

今天群里朋友问到一个问题&#xff1a;这个处理是啥意思&#xff1f; 记录一下。 思路&#xff1a; x为原信号&#xff0c;y为处理后的信号。其中大写为频域信号&#xff0c;小写为时域信号。 考虑到余弦对应的傅里叶变换&#xff0c;以及正弦对应的傅里叶变换&#xff0c;可以…

音频变调技术

今天看到群里有人讨论这个问题&#xff0c;记录一下。 主要内容转自&#xff1a;http://www.cnblogs.com/welen/p/3782896.html 变调和变速原理 自然语音的产生可以简化为图2-1模型&#xff0c;激励源出来的声门波信号与声道模型进行卷积&#xff0c;最后通过嘴唇辐射模型产生语…

图像处理一些常用的网站

一、研究群体 http://www-2.cs.cmu.edu/~cil/vision.html 这是卡奈基梅隆大学的计算机视觉研究组的主页&#xff0c;上面提供很全的资料&#xff0c;从发表文章的下载到演示程序、测试图像、常用链接、相关软硬件&#xff0c;甚至还有一个搜索引擎。 http://www.cmis.csiro.au…

SystemVerilog笔记

SystemVerilog笔记 使用&#xff08;$isunknown&#xff09;操作符&#xff0c;可以在表达式的任意位出现X或Z时返回1。$size函数返回数组的宽度关联数组switch&#xff0c;以实现从字符串到数字的映射。函数exists()来检查元素是否存在。方法unique返回的是在数组中具有唯一值…

收入和贷款有什么关系?

说到贷款&#xff0c;收入是至关重要的一环&#xff0c;收入在贷款审核过程中有着举足轻重的作用。那么具体来说&#xff0c;贷款到底和收入有什么关系呢&#xff1f;贷款审核考察借款人的收入目的是为了核实借款人的偿还能力&#xff0c;因此贷款机构不仅要考核借款人的收入&a…

银行系普惠和小贷系普惠,哪个贷款更靠谱?

2017年5月26日银监会发布了《大中型商业银行设立普惠金融事业部实施方案》&#xff0c;《实施方案》明确了大中型商业银行设立普惠金融事业部的总体目标&#xff0c;通过建立适应普惠金融服务需要的事业部管理体制&#xff0c;构建科学的治理机制和组织架构&#xff0c;健全专业…

并串 转换

并串 转换 题目描述 设计一个模块进行并串转换,要求每四位d输为转到一位dout输出,输出valid_in表示此时的输入有效 输入描述: clk为时钟 rst为低电平复位 d 信号输入 输出描述: dout 信号输出 valid_in 表示输入有效 题目解读 串并转换操作是非常灵活的操作,核心思想就…