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

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
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>
            欧美中文字幕在线| 精品成人国产| 性欧美xxxx视频在线观看| 亚洲精品欧美在线| 欧美激情1区2区3区| 美日韩精品视频| 欧美国产极速在线| 亚洲国产欧美日韩精品| 性色av一区二区三区| 欧美亚洲综合网| 久久国产精品高清| 狂野欧美一区| 欧美成人午夜77777| 老牛嫩草一区二区三区日本| 久久中文欧美| 亚洲欧洲精品成人久久奇米网| 亚洲第一页在线| 一区二区三区四区五区在线| 午夜精品久久久久久久久久久久| 久久狠狠亚洲综合| 欧美一区成人| 极品少妇一区二区三区精品视频| 亚洲精品欧美极品| 亚洲一区二区精品在线| 久久激情网站| 欧美激情一区二区三区全黄| 欧美日韩在线播放三区| 国产麻豆午夜三级精品| 樱桃国产成人精品视频| 国产精品99久久久久久白浆小说| 久久av一区二区三区漫画| 欧美成人免费va影院高清| 日韩一区二区免费高清| 久久经典综合| 国产精品vvv| 亚洲大片av| 欧美一区三区二区在线观看| 亚洲国产99精品国自产| 性欧美激情精品| 欧美日韩在线不卡一区| 激情一区二区三区| 午夜精品区一区二区三| 亚洲欧洲另类| 久久一区亚洲| 国产美女精品免费电影| 亚洲中字在线| 9久草视频在线视频精品| 欧美风情在线观看| 亚洲激情偷拍| 欧美激情一区二区三区高清视频| 欧美在线观看一二区| 国产精品香蕉在线观看| 中日韩男男gay无套| 欧美高清一区| 久久久精品动漫| 国产午夜精品一区二区三区视频 | 亚洲综合电影一区二区三区| 狂野欧美一区| 伊大人香蕉综合8在线视| 久久成人精品视频| 亚洲一二三区精品| 国产精品久久久久久久浪潮网站| 一本色道久久综合亚洲二区三区| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美激情亚洲国产| 久久久午夜视频| 亚洲国产成人porn| 国产日韩综合| 性做久久久久久久免费看| 99精品视频免费| 欧美午夜激情小视频| 亚洲一区二区在线免费观看视频 | 免费欧美日韩| 久热这里只精品99re8久| 亚洲成人在线网| 亚洲国产欧美日韩精品| 欧美精品一区二区蜜臀亚洲| 亚洲伊人观看| 午夜精品久久久久久99热| 国产日韩欧美一区二区| 美女精品在线观看| 亚洲久久成人| 夜夜嗨av一区二区三区中文字幕| 国产精品99免费看| 久久精品国产69国产精品亚洲 | 亚洲图色在线| 海角社区69精品视频| 欧美激情一区二区三区在线 | 国产精品v日韩精品| 久久国产精品久久w女人spa| 久久久久久伊人| 一区二区三区四区国产| 亚洲专区一二三| 在线观看亚洲精品| 一本色道久久综合亚洲精品高清 | 欧美激情二区三区| 香蕉成人久久| 久久伊人精品天天| 亚洲影院色在线观看免费| 久久精品2019中文字幕| 宅男噜噜噜66一区二区| 香蕉久久夜色精品国产使用方法 | 日韩视频永久免费观看| 亚洲一级在线观看| 亚洲日本一区二区三区| 亚洲欧美日韩在线综合| 亚洲精品小视频在线观看| 亚洲一区高清| 日韩视频免费大全中文字幕| 性感少妇一区| 亚洲图片欧洲图片av| 久久免费偷拍视频| 亚洲在线成人精品| 农村妇女精品| 久久精品欧美日韩精品| 欧美日韩午夜剧场| 国产精品男人爽免费视频1 | 老司机67194精品线观看| 欧美性大战久久久久久久| 欧美激情黄色片| 国产综合色一区二区三区| 一本色道久久综合精品竹菊| 亚洲激情一区二区三区| 久久精品国产精品亚洲精品| 欧美一区二区三区另类| 亚洲一区国产| 欧美精品在欧美一区二区少妇| 久久一区二区三区国产精品| 国产三区精品| 亚洲一区中文字幕在线观看| 一本久道久久综合婷婷鲸鱼| 免费欧美电影| 欧美成人自拍| 亚洲国产精品悠悠久久琪琪| 性欧美videos另类喷潮| 久久久久久久高潮| 国产一区二区在线免费观看| 亚洲一区在线视频| 欧美中文在线观看| 国产精品伊人日日| 欧美亚洲网站| 久久久久国产一区二区三区| 国内精品模特av私拍在线观看 | 欧美日韩一区二区在线视频| 99国产麻豆精品| 亚洲女优在线| 国产亚洲激情在线| 久久天堂成人| 亚洲黄色av| 亚洲一区二区久久| 国产精品男女猛烈高潮激情 | 国产日韩欧美综合在线| 久久av老司机精品网站导航| 久久亚洲精品视频| 亚洲第一在线综合在线| 欧美va天堂| 99视频热这里只有精品免费| 亚洲欧美视频一区| 精品成人免费| 欧美日韩国产成人在线观看| 亚洲一区二区在线播放| 久久久成人网| 亚洲看片一区| 国产精品黄页免费高清在线观看| 亚洲欧美日韩精品久久奇米色影视 | 悠悠资源网亚洲青| 欧美国产日韩一区二区| 亚洲香蕉网站| 欧美成人免费在线观看| 在线视频日韩精品| 国产日韩在线一区二区三区| 免费在线亚洲欧美| 亚洲一区二区三区免费观看| 蜜桃av综合| 亚洲视频在线一区观看| 欧美综合国产| 欧美午夜免费电影| 久久成人精品无人区| 亚洲第一主播视频| 欧美有码在线观看视频| 亚洲人成高清| 国产午夜久久| 欧美视频在线观看视频极品| 久热re这里精品视频在线6| 国产精品99久久久久久宅男| 欧美电影免费观看大全| 午夜亚洲视频| 一区二区国产日产| 尤物yw午夜国产精品视频| 国产精品久久久久久久久久尿| 六月婷婷一区| 久久激情视频| 午夜久久一区| 一区二区三区日韩欧美精品| 欧美国产高清| 欧美国产大片| 免费成人毛片| 麻豆av福利av久久av| 久久gogo国模裸体人体| 亚洲一区二区少妇|