青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

CPU親合力(CPU Affinity)

轉載自:http://blog.csdn.net/normalnotebook/archive/2006/06/03/771581.aspx

CPU Affinity

作者:Robert Love   翻譯:normalnotebook
Bind specific processes to specific processors with a new system call.
使用新的系統(tǒng)調用,可以將一個進程綁定到一個特定的CPU上運行。

The ability in Linux to bind one or more processes to one or more processors, called CPU affinity, is a long-requested feature. The idea is to say ``always run this process on processor one'' or ``run these processes on all processors but processor zero''. The scheduler then obeys the order, and the process runs only on the allowed processors.

       CPU親合力就是指在Linux中能夠將一個或多個進程綁定到一個或多個處理器上運行,這是期待已久的特性。也就是說:“在1號處理器上一直運行該程序”或者是“在所有的處理器上運行這些程序,而不是在0號處理器上運行”。然后,調度器將遵循該規(guī)則,程序僅僅運行在允許的處理器上。

Other operating systems, such as Windows NT, have long provided a system call to set the CPU affinity for a process. Consequently, demand for such a system call in Linux has been high. Finally, the 2.5 kernel introduced a set of system calls for setting and retrieving the CPU affinity of a process.

        其他類型的操作系統(tǒng),比如Windows NT,很早以前就開始提供系統(tǒng)調用,用于設置應用程序的CPU親合力。因此,要求Linux也提供這樣的系統(tǒng)調用的呼聲日益高漲。最終在2.5內核中,引入了一套系統(tǒng)調用用于設置和獲取某個進程的CPU親合力特性。

In this article, I look at the reasons for introducing a CPU affinity interface to Linux. I then cover how to use the interface in your programs. If you are not a programmer or if you have an existing program you are unable to modify, I cover a simple utility for changing the affinity of a given process using its PID. Finally, we look at the actual implementation of the system call.

       本文將探討CPU親合力被引入到Linux中的動機,以及在應用程序中如何使用親合力接口。假如你不是一個程序員或者你擁有一個程序,但又不想修改它,那么我將運用一套簡單的工具,通過PID改變給定進程的親合力。最后,我們將探討親合力系統(tǒng)調用的具體實現(xiàn)原理。

Soft vs. Hard CPU Affinity

軟親合力 VS. 硬親合力

There are two types of CPU affinity. The first, soft affinity, also called natural affinity, is the tendency of a scheduler to try to keep processes on the same CPU as long as possible. It is merely an attempt; if it is ever infeasible, the processes certainly will migrate to another processor. The new O(1) scheduler in 2.5 exhibits excellent natural affinity. On the opposite end, however, is the 2.4 scheduler, which has poor CPU affinity. This behavior results in the ping-pong effect. The scheduler bounces processes between multiple processors each time they are scheduled and rescheduled. Table 1 is an example of poor natural affinity; Table 2 shows what good natural affinity looks like.

  time 1 time 2 time 3 time 4
Process A CPU 0 CPU 1 CPU 0 CPU 1

Table 1. The Ping-Pong Effect

  time 1 time 2 time 3 time 4
Process A CPU 0 CPU 0 CPU 0 CPU 0

Table 2. Good Affinitiy

Hard affinity, on the other hand, is what a CPU affinity system call provides. It is a requirement, and processes must adhere to a specified hard affinity. If a processor is bound to CPU zero, for example, then it can run only on CPU zero.

Why One Needs CPU Affinity

Before we cover the new system calls, let's discuss why anyone would need such a feature. The first benefit of CPU affinity is optimizing cache performance. I said the O(1) scheduler tries hard to keep tasks on the same processor, and it does. But in some performance-critical situations--perhaps a large database or a highly threaded Java server--it makes sense to enforce the affinity as a hard requirement. Multiprocessing computers go through a lot of trouble to keep the processor caches valid. Data can be kept in only one processor's cache at a time. Otherwise, the processor's cache may grow out of sync, leading to the question, who has the data that is the most up-to-date copy of the main memory? Consequently, whenever a processor adds a line of data to its local cache, all the other processors in the system also caching it must invalidate that data. This invalidation is costly and unpleasant. But the real problem comes into play when processes bounce between processors: they constantly cause cache invalidations, and the data they want is never in the cache when they need it. Thus, cache miss rates grow very large. CPU affinity protects against this and improves cache performance.

A second benefit of CPU affinity is a corollary to the first. If multiple threads are accessing the same data, it might make sense to bind them all to the same processor. Doing so guarantees that the threads do not contend over data and cause cache misses. This does diminish the performance gained from multithreading on SMP. If the threads are inherently serialized, however, the improved cache hit rate may be worth it.

The third and final benefit is found in real-time or otherwise time-sensitive applications. In this approach, all the system processes are bound to a subset of the processors on the system. The specialized application then is bound to the remaining processors. Commonly, in a dual-processor system, the specialized application is bound to one processor, and all other processes are bound to the other. This ensures that the specialized application receives the full attention of the processor.

Getting the New System Calls

The system calls are new, so they are not available yet in all systems. You need at least kernel 2.5.8-pre3 and glibc 2.3.1; glibc 2.3.0 supports the system calls, but it has a bug. The system calls are not yet in 2.4, but patches are available at www.kernel.org/pub/linux/kernel/people/rml/cpu-affinity.

Many distribution kernels also support the new system calls. In particular, Red Hat 9 is shipping with both kernel and glibc support for the new calls. Real-time solutions, such as MontaVista Linux, also fully support the new interface.

Affinity Masks

On most systems, Linux included, the interface for setting CPU affinity uses a bitmask. A bitmask is a series of n bits, where each bit individually corresponds to the status of some other object. For example, CPU affinity (on 32-bit machines) is represented by a 32-bit bitmask. Each bit represents whether the given task is bound to the corresponding processor. Count the bits from right to left, bit 0 to bit 31 and, thus, processor zero to processor 31. For example:

11111111111111111111111111111111 = 4,294,967,295

is the default CPU affinity mask for all processes. Because all bits are set, the process can run on any processor. Conversely:

00000000000000000000000000000001 = 1

is much more restrictive. Only bit 0 is set, so the process may run only on processor zero. That is, this affinity mask binds a process to processor zero. 

Get it? What do the next two masks equal in decimal? What is the result of using them as the affinity mask of a process?

10000000000000000000000000000000
00000000000000000000000000000011

The first is equal to 2,147,483,648 and, because bit 31 is set, binds the process to processor number 31. The second is equal to 3, and it binds the process in question to processor zero and processor one.

The Linux CPU affinity interface uses a bitmask like that shown above. Unfortunately, C does not support binary constants, so you always have to use the decimal or hexadecimal equivalent. You may get a compiler warning for very large decimal constants that set bit 31, but they will work.

Using the New System Calls

With the correct kernel and glibc in hand, using the system calls is easy:

#define _GNU_SOURCE
#include <sched.h>
long
sched_setaffinity(pid_t pid, unsigned int len,
unsigned long *user_mask_ptr);
long
sched_getaffinity(pid_t pid, unsigned int len,
unsigned long *user_mask_ptr);

The first system call is used to set the affinity of a process, and the second system call retrieves it.

In either system call, the PID argument is the PID of the process whose mask you wish to set or retrieve. If the PID is set to zero, the PID of the current task is used.

The second argument is the length in bytes of the CPU affinity bitmask, currently four bytes (32 bits). This number is included in case the kernel ever changes the size of the CPU affinity mask and allows the system calls to be forward-compatible with any changes; breaking syscalls is bad form, after all. The third argument is a pointer to the bitmask itself.

Let us look at retrieving the CPU affinity of a task:

unsigned long mask;
unsigned int len = sizeof(mask);
if (sched_getaffinity(0, len, &mask) < 0) {
perror("sched_getaffinity");
return -1;
}
printf("my affinity mask is: %08lx\n", mask);

As a convenience, the returned mask is binary ANDed against the mask of all processors in the system. Thus, processors in your system that are not on-line have corresponding bits that are not set. For example, a uniprocessor system always returns 1 for the above call (bit 0 is set and no others).

Setting the mask is equally easy:

unsigned long mask = 7; /* processors 0, 1, and 2 */
unsigned int len = sizeof(mask);
if (sched_setaffinity(0, len, &mask) < 0) {
perror("sched_setaffinity");
}

This example binds the current process to the first three processors in the system.

You then can call sched_getaffinity() to ensure the change took effect. What does sched_getaffinity() return for the above setup if you have only two processors? What if you have only one? The system call fails unless at least one processor in the bitmask exists. Using a mask of zero always fails. Likewise, binding to processor seven if you do not have a processor seven will fail.

It is possible to retrieve the CPU affinity mask of any process on the system. You can set the affinity of only the processes you own, however. Of course, root can set any process' affinity.

I Want a Tool!

If you are not a programmer, or if you cannot modify the source for whatever reason, you still can bind processes. Listing 1 is the source code for a simple command-line utility to set the CPU affinity mask of any process, given its PID. As we discussed above, you must own the process or be root to do this.

Listing 1. bind

Usage is simple; once you learn the decimal equivalent of the CPU mask, you need:

usage: bind pid cpu_mask

As an example, assume we have a dual computer and want to bind our Quake process (with PID 1600) to processor two. We would enter the following:

bind 1600 2



Getting Really Crafty

In the previous example, we bound Quake to one of the two processors in our system. To ensure top-notch frame rates, we need to bind all the other processes on the system to the other processor. You can do this by hand or by writing a crafty script, but neither is efficient. Instead, make use of the fact that CPU affinity is inherited across a fork(). All of a process' children receive the same CPU affinity mask as their parent.

Then, all we need to do is have init bind itself to one processor. All other processes, by nature of init being the root of the process tree and thus the superparent of all processes, are then likewise bound to the one processor.

The cleanest way to do this type of bind is to hack this feature into init itself and pass in the desired CPU affinity mask using the kernel command line. We can accomplish our goal with a simpler solution, though, without having to modify and recompile init. Instead, we can edit the system startup script. On most systems this is /etc/rc.d/rc.sysinit or /etc/rc.sysinit, the first script run by init. Place the sample bind program in /bin, and add these lines to the start of rc.sysinit:

/bin/bind 1 1
/bin/bind $ 1

These lines bind init (whose PID is one) and the current process to processor zero. All future processes will fork from one of these two processes and thus inherit the CPU affinity mask. You then can bind your process (whether it be a real-time nuclear control system or Quake) to processor one. All processes will run on processor zero except our special process (and any children), which will run on processor one. This ensures that the entire processor is available for our special process.

Kernel Implementation of CPU Affinity

Long before Linus merged the CPU affinity system calls, the kernel supported and respected a CPU affinity mask. There was no interface by which user space could set the mask.

Each process' mask is stored in its task_struct as an unsigned long, cpus_allowed. The task_struct structure is called the process descriptor. It stores all the information about a process. The CPU affinity interface merely reads and writes cpus_allowed.

Whenever the kernel attempts to migrate a process from one processor to another, it first checks to see if the destination processor's bit is set in cpus_allowed. If the bit is not set, the kernel does not migrate the process. Further, whenever the CPU affinity mask is changed, if the process is no longer on an allowed processor it is migrated to one that is allowed. This ensures the process begins on a legal processor and can migrate only to a legal processor. Of course, if it is bound to only a single processor, it does not migrate anywhere.

Conclusion

The CPU affinity interface introduced in 2.5 and back-ported elsewhere provides a simple yet powerful mechanism for controlling which processes are scheduled onto which processors. Users with more than one processor may find the system calls useful in squeezing another drop of performance out of their systems or for ensuring that processor time is available for even the most demanding real-time task. Of course, users with only one processor need not feel left out. They also can use the system calls, but they aren't going to be too useful.

posted on 2010-10-31 17:00 楊粼波 閱讀(966) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美性猛交99久久久久99按摩| 亚洲第一中文字幕在线观看| 国产日产精品一区二区三区四区的观看方式 | 久久久久久久91| 狠狠综合久久av一区二区老牛| 亚洲一区二区三区四区视频| 国产精品99久久久久久久vr | 在线欧美一区| 欧美凹凸一区二区三区视频| 噜噜噜在线观看免费视频日韩| 亚洲国产精品精华液2区45| 亚洲天堂av在线免费观看| 亚洲精品日韩在线| 亚洲国产日韩综合一区| 亚洲精品一区二区三区福利| 欧美激情综合五月色丁香小说| 日韩一级成人av| 亚洲五月婷婷| 欧美大色视频| 亚洲视频第一页| 性做久久久久久久久| 亚洲高清精品中出| 亚洲精品视频中文字幕| 国产精品成人在线观看| 久久一区二区三区av| 欧美国产日韩a欧美在线观看| 亚洲一区成人| 久久久另类综合| 亚洲自拍偷拍福利| 久久久青草青青国产亚洲免观| 精品动漫av| 亚洲精品国产品国语在线app | 亚洲毛片网站| 亚洲免费综合| 亚洲国产综合在线| 亚洲午夜在线观看视频在线| 亚洲第一精品在线| 亚洲影院免费观看| 日韩视频一区二区三区在线播放| 亚洲一区二区在线播放| 亚洲精品色婷婷福利天堂| 欧美在线观看一区二区| 亚洲国产日韩一区二区| 午夜精品剧场| 亚洲一区激情| 欧美激情第一页xxx| 久久只精品国产| 国产无一区二区| 亚洲一区国产视频| 欧美日韩一区二区三区四区五区| 欧美日韩精品不卡| 在线看日韩av| 亚洲伊人伊色伊影伊综合网| 亚洲人体一区| 久久免费视频网| 久久精品官网| 国产精品日韩在线观看| 一本色道久久综合亚洲精品高清 | 国内伊人久久久久久网站视频| 日韩视频永久免费| 夜夜嗨av色综合久久久综合网| 女仆av观看一区| 欧美在线视频播放| 午夜日韩激情| 国产精品高潮呻吟视频| 99精品国产在热久久| 亚洲最新色图| 午夜国产精品视频| 蜜桃久久av| 蜜臀91精品一区二区三区| 国产亚洲精品福利| 午夜精品成人在线| 久久er精品视频| 国产日韩精品一区二区| 亚洲免费影视第一页| 欧美一级久久| 国产日韩精品视频一区二区三区| 性娇小13――14欧美| 欧美中日韩免费视频| 含羞草久久爱69一区| 久久久久久久91| 亚洲第一毛片| 日韩视频一区二区三区在线播放 | 一本一本大道香蕉久在线精品| 一区二区三区导航| 国产精品国产三级国产aⅴ浪潮| 亚洲视频在线视频| 亚洲一区二区在线视频| 亚洲欧美春色| 久久久国际精品| 亚洲第一二三四五区| 欧美区在线播放| 亚洲影视在线播放| 久久午夜国产精品| 亚洲精品一品区二品区三品区| 欧美日韩三级电影在线| 亚洲欧美中文在线视频| 欧美大胆a视频| 亚洲一区二区三| 国内成+人亚洲| 欧美精品国产| 香蕉久久一区二区不卡无毒影院 | 亚洲成色777777女色窝| 欧美日韩中文在线| 欧美激情精品久久久久久大尺度 | 国产亚洲成av人片在线观看桃| 久久青青草综合| 亚洲午夜精品| 国产精品日本欧美一区二区三区| 午夜亚洲视频| 亚洲人成绝费网站色www| 久久不射2019中文字幕| 亚洲精品美女在线| 国产在线精品二区| 欧美日韩三级| 蜜臀av一级做a爰片久久| 亚洲主播在线观看| 亚洲国产精品一区二区三区| 久久精品国产精品| 中文日韩在线| 日韩亚洲欧美高清| 国自产拍偷拍福利精品免费一| 欧美午夜一区| 欧美精品18videos性欧美| 久久久精品一区| 午夜精品福利在线| 国产精品成人观看视频免费| 欧美高清视频一区| 亚洲欧美成人网| 日韩视频免费观看高清在线视频| 免费成人av资源网| 欧美大片一区二区| 在线一区亚洲| 一本色道久久综合亚洲精品按摩 | 亚洲国产精品va在线观看黑人| 国产精品人人做人人爽人人添| 欧美日韩第一区| 欧美激情二区三区| 欧美成人黄色小视频| 久久综合中文色婷婷| 久久精品国产99精品国产亚洲性色| 欧美一区二区三区四区高清| 亚洲视频成人| 亚洲欧美日韩网| 亚洲自拍偷拍麻豆| 亚洲欧美日韩精品久久亚洲区 | 欧美福利网址| 狼人天天伊人久久| 久久久久久久久久久一区| 欧美一区二区三区视频在线| 午夜欧美大尺度福利影院在线看 | 欧美96在线丨欧| 欧美国产日韩视频| 亚洲区一区二区三区| 亚洲日本电影| 亚洲一区二区三区免费视频 | 男人的天堂亚洲| 欧美成人影音| 日韩视频免费在线观看| 亚洲小说区图片区| 欧美在线免费视频| 久久婷婷人人澡人人喊人人爽 | 一区二区免费在线观看| 亚洲男人的天堂在线| 欧美专区日韩专区| 欧美成人午夜激情视频| 正在播放亚洲| 亚洲女人小视频在线观看| 欧美一级网站| 榴莲视频成人在线观看| 欧美日韩国产综合一区二区| 国产精品九九| 亚洲第一区在线观看| 中国av一区| 麻豆成人在线| 一本大道久久a久久综合婷婷| 亚洲欧美国产精品va在线观看| 久久久噜噜噜久久中文字幕色伊伊| 欧美韩日一区二区| 国产精品网站在线观看| 亚洲福利视频一区| 亚洲综合三区| 免费影视亚洲| 亚洲视频电影在线| 久久噜噜噜精品国产亚洲综合 | 亚洲一区免费网站| 久久午夜精品一区二区| 欧美国产激情| 激情小说亚洲一区| 99av国产精品欲麻豆| 欧美日韩伦理在线免费| 久久午夜av| 国产精品久久久久一区| 伊人久久综合97精品| 亚洲午夜视频在线| 欧美大片免费观看| 午夜精品久久久久久久男人的天堂 | 在线成人黄色| 欧美在线免费| 亚洲美女毛片|