我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。
如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。
Amdahl 法则说明这种加速比在现实中可能并不会发生,但是可以非常接近于该值。对于通常情况来说,我们可以推论出每个程序都有一些串行的组件。随着问题集不断变大,串行组件最终会在优化解决方案时间方面达到一个上限。
Amdahl 法则在希望保持高 CPU 缓存命中率时尤其重要。如果一个给定的进程迁移到其他地方去了,那么它就失去了利用 CPU 缓存的优势。实际上,如果正在使用的 CPU 需要为自己缓存一些特殊的数据,那么所有其他 CPU 都会使这些数据在自己的缓存中失效。
这个方法让程序能够自己确定要让多少个处理器保持繁忙,例如缺省让所有的处理器都处于繁忙状态,并允许用户指定系统中实际处理器范围的一个子集。
|
回首2011,算是不幸的一年,步入了人们人人恐惧的计算机软件行业,软件行业也是在很多人一直看来是所谓的白领高薪行业,但是在这个高薪白领行业里又有多少人知道其背后的艰辛与“痛苦”呢,何况他也不算是什么高薪行业
与软件结缘
2.数据结构(计算机的灵魂)
回首2010,1.76,我像很多人高考生一样,步入了自己心目中期待已久的大学校园,在当时,我们把大学想象的那么的美好,可以疯狂地玩游戏,疯狂喝酒,甚至疯狂地谈恋爱。。。步入大学的第一堂课就是可爱的班主任的计算机文化基础课,也是这一节课,给了我一个知名的打击,photoshop,frontpage,dreamweaver,内存,硬件,注册表,软件。。。。。看着一个个计算机名词,我懵了,这些都是什么啊?难道我学的软件专业是这样的吗?也是从那开始,原来我所选的专业是计算机类的专业啊,计算机,我懂什么啊?毫不疑问,我什么也不懂,这一切对我来说好像当头一棒一样的打在了我头上。但是这时的我也不是一个孩子了,既然选择了,就要把他学好,虽然什么也不懂。。。
2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现 硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。
现在让我们来设计一个程序,它可以让 Linux 系统非常繁忙。可以使用前面介绍的系统调用和另外一些用来说明系统中有多少处理器的 API 来构建这个应用程序。实际上,我们的目标是编写这样一个程序:它可以让系统中的每个处理器都繁忙几秒钟。可以从后面的“下载”一节中。
补充能量,学习理论
基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。
期待已久的暑假终于到临,学校给参加软件大赛的开放机房,集体在一块开发项目。。。暑假的这一个月,说实话,每天都很累,每天都会遇到各种各样的问题,我们队的两个女生(美工)明显有点吃不消了。。但是大家都还是很努力。。。。经过一个月的努力,项目终于完成的了。。大家都很高兴。。说实话,这一个多月,虽然很累,但是很充实。。。
一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。
简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
3.微机原理
第一次真正的软件开发
通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU 之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。
/* 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。
因此,如果有多个线程都需要相同的数据,那么将这些线程绑定到一个特定的 CPU 上是非常有意义的,这样就确保它们可以访问相同的缓存数据(或者至少可以提高缓存的命中率)。否则,这些线程可能会在不同的 CPU 上执行,这样会频繁地使其他缓存项失效。
下面的样例应用程序显示了这是如何工作的。
总结2011
暑假开学后,慢慢的发现自己在同学中已经小有名气了。。。在他们看来自己好像变成了一个高手(注:由于我们学校差不多是以java的路线培养,大一下学期完了我们才学完java的基本语法和面向对象的一点内容),慢慢的我也发现,自己确实比别人稍微懂得多点了。。。嘿嘿,小自恋一下。但是我当然不满足现在的一点小成就。。。。根据技术的稍微提高,我越来越发现自己理论的空缺,很多东西,一些基本的理论不懂事很难理解。。。进入大二之后,我开始着手理论上的学习,通过查找资料发现,很多理论上的东西都是基于c语言,于是我先开始了c语言的学习,在学习c语言的过程中,由于有了java的基础,所以学起c语言来,感觉比较容易了。。。但是我感觉自己对c语言的学习很失败,感觉没有学到其内涵,现在学完了。。一点感觉也没有,感觉只是学了点表面的东西,哎,没办法,谁叫咱菜啊。。。
回想从真正java入门到现在已经算是差不多有快一年的时间了吧。。。自己这点小成就在大多数大牛面前真是不值得一提啊。。回想这一年的收获和付出,其实自己一直就是处于一个菜鸟级别上,一直想努力往上爬,却一直没爬上来,。自己理论上的欠缺,一定会是自己提高上的绊脚石,没办法,谁叫咱是专科,学校专科培养就是面向就业的。。。我感觉培养出的就业的人以后也是码奴一级的人物,我不想做码奴,所以我只能去努力。。。。去学习那些自己欠缺的东西
经过这一个月的魔鬼项目开发,我明显的感觉到了自己技术上的提高,虽然在暑假就学习了一个struts2的新技术,但是我感觉这一个月思想上的提高绝对高于这新技术上的提高。。。。
每个设置的位都对应一个可以合法调度的 CPU,而未设置的位则对应一个不可调度的 CPU。换而言之,进程都被绑定了,只能在那些对应位被设置了的处理器上运行,私服网站。通常,掩码中的所有位都被置位了。这些线程的亲和性(affinity)都会传递给从它们派生的子进程中。
测试复杂软件是我们对内核的亲和性(affinity)技术感兴趣的另外一个原因。考虑一个需要进行线性可伸缩性测试的应用程序。有些产品声明可以在 使用更多硬件 时执行得更好。
亲和性(affinity)掩码是使用在 mask 中存储的位掩码来表示的。最低位对应于系统中的第一个逻辑处理器,而最高位则对应于系统中最后一个逻辑处理器。
有了第一次接项目的经历,慢慢的也开始自己尝试去做东西了,从大二开学到现在快半年了。。。自己也断断续续的做了几个小项目,只不过都不算太好。。。。
由于在同学之间小有名气,一天一同学给我说,外面有一家网络公司招人帮他们给别人做网站,问我能不能行,我抱着尝试的态度说:行,我试试吧。。说实话,这对我真是一个挑战,幸亏有我的合作伙伴(小金金)一块做前台,我的前台技术实在不敢恭维啊。。经过我们两个的五天奋战。一个商业网站终于完成了。。前台后台感觉还挺不错。。哎,唯一遗憾的是,那网络公司由于我们做的“太丑”,竟然不用我们的网站,没办法,谁叫咱菜啊。。。。。
如果应用程序随着 CPU 的增加可以线性地伸缩,那么每秒事务数和 CPU 个数之间应该会是线性的关系(例如斜线图 ?? 请参阅下一节的内容)。这样建模可以确定应用程序是否可以有效地使用底层硬件。
注意,cpu_affinity 会被传递给子线程,因此应该适当地调用 sched_set_affinity。
作者:
来源:http://www.ibm.com/developerworks/cn/linux/l-affinity.html
1.c语言复习
学习c语言一个月之后,又回到了java里面,暑假学习了struts2,中变传奇私服,感觉框架用起来挺爽的,于是学完c语言之后开始了hibernate的学习,
|
在 Linux 内核中,所有的进程都有一个相关的数据结构,称为 task_struct。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是cpus_allowed 位掩码。这个位掩码由n 位组成,与系统中的 n 个逻辑处理器一一对应。 具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。
如果有时间话在看看计算机网络,趁着自己还没有毕业,能多补充点能量就多补充点吧。。。。
大学接触的第一门编程是java,在我的印象里,java只是手机里面的一个东西,对他一点概念也没有,上完第一节课,对java的印象就是老师的那一句话:everythingisobjectinjava‘sworld,传奇私服登录器。。。。进入软件行业的一切好像都不那么顺利,没办法还是硬着头皮继续往下走吧。。。。。
学习hibernate是一段比较难熬的日子,那些配置文件搞得我整天晕晕的。。现在想想,由于学完没用过,好像都忘得差不多了,,呵呵,幸亏做了笔记。。。
/* 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 繁忙。我们可以使用另外一个方法来确定系统中有多少个处理器: