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

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
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.
使用新的系統調用,可以將一個進程綁定到一個特定的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號處理器上運行”。然后,調度器將遵循該規則,程序僅僅運行在允許的處理器上。

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.

        其他類型的操作系統,比如Windows NT,很早以前就開始提供系統調用,用于設置應用程序的CPU親合力。因此,要求Linux也提供這樣的系統調用的呼聲日益高漲。最終在2.5內核中,引入了一套系統調用用于設置和獲取某個進程的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改變給定進程的親合力。最后,我們將探討親合力系統調用的具體實現原理。

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>
            欧美一区高清| 国内精品久久久久久 | 韩国v欧美v日本v亚洲v| 久热re这里精品视频在线6| 久久九九免费视频| 亚洲一区二区三区视频播放| 亚洲国产精品一区二区第一页| 激情视频亚洲| 在线看日韩av| 亚洲国产日韩欧美| 亚洲精品乱码久久久久久| 亚洲精品黄色| 在线亚洲美日韩| 国产精品久久久999| 欧美日韩一区在线视频| 欧美第一黄色网| 欧美了一区在线观看| 欧美激情综合色| 欧美日韩一二三区| 国产精品成人在线观看| 国产精品区二区三区日本| 国产乱子伦一区二区三区国色天香| 欧美大色视频| 欧美三级网址| 国内精品嫩模av私拍在线观看| 亚洲国产清纯| 欧美在线高清| 亚洲国产片色| 亚洲精品韩国| 欧美专区一区二区三区| 欧美成人福利视频| 国产精品一区二区欧美| 国产亚洲精品bt天堂精选| 亚洲国产成人精品久久| 亚洲一区视频| 欧美高清不卡| 亚洲综合999| 欧美成人午夜免费视在线看片 | 午夜一级久久| 欧美成人高清| 久久婷婷丁香| 欧美精品自拍| 亚洲人成网站在线观看播放| 欧美在线免费观看亚洲| 中文av字幕一区| 亚洲高清一二三区| 91久久综合| 亚洲一级黄色片| 久久久xxx| 欧美亚洲一区二区三区| 一本大道久久精品懂色aⅴ| 欧美在线免费观看视频| 久久精品国产免费观看| 香蕉成人久久| 一区二区av在线| 亚洲性视频h| 老色鬼精品视频在线观看播放| 亚洲欧美成aⅴ人在线观看| 亚洲乱码精品一二三四区日韩在线| 亚洲经典视频在线观看| 亚洲老板91色精品久久| 亚洲影视九九影院在线观看| 亚洲无限乱码一二三四麻| 久久精品国产亚洲精品| 亚洲激情另类| 久久久久国产免费免费| 欧美日韩国产高清| 亚洲第一搞黄网站| 亚洲精品视频一区二区三区| 久久久999国产| 一区二区三区四区五区视频 | 黄色成人91| 亚洲男女自偷自拍| 久久精品国产精品亚洲| 欧美成人日韩| 久久精品亚洲国产奇米99| 欧美伦理影院| 亚洲大片在线| 麻豆av福利av久久av| 午夜精品美女久久久久av福利| 欧美日韩精品一二三区| 亚洲精品国精品久久99热| 欧美aⅴ一区二区三区视频| 欧美亚洲色图校园春色| 国产精品久久久久久五月尺| aⅴ色国产欧美| 亚洲国产欧美一区二区三区久久 | 日韩视频在线你懂得| 蘑菇福利视频一区播放| 亚洲高清久久| 亚洲第一毛片| 欧美成人一区二区三区| 亚洲另类自拍| 亚洲精品孕妇| 国产精品久久久久天堂| 午夜久久tv| 一区二区三区欧美| 鲁大师影院一区二区三区| 在线日韩中文| 亚洲高清在线观看| 欧美国产乱视频| 久久综合五月| 亚洲精品久久7777| 最新国产成人av网站网址麻豆| 米奇777在线欧美播放| 亚洲精品123区| 亚洲第一级黄色片| 欧美日韩大陆在线| 亚洲免费在线视频| 欧美一区二区视频网站| 亚洲国语精品自产拍在线观看| 亚洲国产美女久久久久| 欧美午夜精品久久久| 欧美一区激情| 美国十次了思思久久精品导航| 99精品热视频| 午夜久久久久| 亚洲美女色禁图| 亚洲高清视频在线观看| 欧美日韩一区二区免费在线观看| 亚洲一二三区视频在线观看| 亚洲男女毛片无遮挡| 在线国产精品播放| 日韩一级黄色大片| 狠狠操狠狠色综合网| 亚洲欧洲精品一区| 国产日韩欧美一区二区三区在线观看 | 亚洲精美视频| 亚洲一区日本| 亚洲国产美国国产综合一区二区| 亚洲免费播放| 在线观看欧美激情| 亚洲一级黄色片| 亚洲日本视频| 久久九九国产精品怡红院| 欧美午夜剧场| 亚洲性视频h| 欧美成人高清| 久久视频精品在线| 国产精品人人爽人人做我的可爱| 欧美激情a∨在线视频播放| 国产精品久久久久久影视| 亚洲国产日韩在线| 亚洲国产精品ⅴa在线观看| 亚洲午夜国产成人av电影男同| 1769国内精品视频在线播放| 亚洲欧美日韩一区在线观看| 美女日韩在线中文字幕| 欧美一区二区高清| 欧美视频手机在线| 亚洲精品中文字幕在线观看| 亚洲福利一区| 久久精品国产亚洲一区二区| 亚洲一区二区三区影院| 欧美激情在线免费观看| 欧美刺激性大交免费视频| 影院欧美亚洲| 免费观看成人www动漫视频| 国产精品不卡在线| 亚洲美女毛片| 99视频+国产日韩欧美| 亚洲午夜性刺激影院| 亚洲人成小说网站色在线| 久久永久免费| 老色鬼久久亚洲一区二区| 国产综合网站| 久久精品91久久久久久再现| 欧美在线视频观看| 国产亚洲aⅴaaaaaa毛片| 亚洲欧美日韩国产成人| 欧美中文在线观看国产| 国产日韩亚洲欧美| 欧美亚洲一区三区| 麻豆freexxxx性91精品| 黄色av日韩| 久久一综合视频| 欧美成年人网站| 日韩写真视频在线观看| 欧美视频在线观看免费网址| 国产精品99久久99久久久二8| 亚洲一区www| 国产欧美日韩视频一区二区| 亚洲午夜伦理| 久久久久久一区二区三区| 国产视频欧美| 欧美二区在线播放| 亚洲视频综合在线| 久久久亚洲一区| 亚洲国产精品一区二区尤物区| 免费亚洲网站| 亚洲午夜小视频| 亚洲综合成人在线| 国产精品影音先锋| 裸体丰满少妇做受久久99精品| 亚洲麻豆av| 久久精品国产亚洲精品| 亚洲国产一区二区a毛片| 欧美午夜不卡| 久久精品国产免费| 在线亚洲激情|