티스토리 뷰

Developer

[linux] cpu affinity.

rocksea 2014. 2. 19. 11:09

cpu affinity에 대해 소개하고자 합니다.

cpu affinity란 특정 코어를 지정해서 task를 수행 하도록 설계된 Concept입니다.

linux kernel 2.6 이상부터 포함되었으며 최근 나오는 오픈소스에 왠만하면 대부분 지원하고 있습니다.


예로 nginx의 경우 입니다.

Linux only.

With this option you can bind the worker process to a CPU, it calls sched_setaffinity().

For example,

worker_processes     4;

worker_cpu_affinity 0001 0010 0100 1000;

Bind each worker process to one CPU only.

worker_processes     2;

worker_cpu_affinity 0101 1010;

Bind the first worker to CPU0/CPU2, bind the second worker to CPU1/CPU3. This is suitable for HTT.


각 worker thread에 대한 CPU사용에 대한 지정이 가능합니다.

CPU 코어가 4개라고 가정 할 경우

4개의 worker process를 생성하여 각각의 CPU에서 처리하는 방법이 있는가 하면 2개의 worker

process만 생성하여 1개의 worker에 2개의 core를 할당하는 방법이 있습니다.  시스템 특성에 맞추어

조절하여 사용하면 됩니다.


Linux  C 코드 예제.

cpu_affinity.c

#include <stdio.h>
#include <math.h>
#include <unistd.h>
#define __USE_GNU
#include <sched.h>
double waste_time(long n)
{
    double res = 0;
    long i = 0;
    while(i <n * 200000) {
        i++;
        res += sqrt (i);
    }
    return res;
}
int main(int argc, char **argv)
{
    unsigned long mask = 1; /* processor 0 */
    /* bind process to processor 0 */
    if (sched_setaffinity(0, sizeof(mask), (cpu_set_t*)&mask) <0) {
        perror("sched_setaffinity");
    }
    /* waste some time so the work is visible with "top" */
    printf ("result: %f\n", waste_time (2000));
    mask = 2; /* process switches to processor 1 now */
    if (sched_setaffinity(0, sizeof(mask), (cpu_set_t*)&mask) <0) {
        perror("sched_setaffinity");
    }
    /* waste some more time to see the processor switch */
    printf ("result: %f\n", waste_time (2000));
    return 0;

}


Compile

$ gcc -o cpu_affinity cpu_affinity.c  -lm

./cpu_affinity


Thread형 함수도 따로 존재한다.

cpu_affinity_thread.c

#include <stdio.h>
#include <math.h>
#include <unistd.h>
#define __USE_GNU
#include <pthread.h>
double waste_time(long n)
{
 double res = 0;
 long i = 0;
 while (i <n * 200000) {
 i++;
 res += sqrt(i);
 }
 return res;
}
void *thread_func(void *param)
{
 unsigned long mask = 1; /* processor 0 */
 /* bind process to processor 0 */
 if (pthread_setaffinity_np(pthread_self(), sizeof(mask), (cpu_set_t *)&mask) <0) {
  perror("pthread_setaffinity_np");
 }
 /* waste some time so the work is visible with "top" */
 printf("result: %f\n", waste_time(2000));
 mask = 2;  /* process switches to processor 1 now */
 sleep(2);
 if (pthread_setaffinity_np(pthread_self(), sizeof(mask), (cpu_set_t *)&mask) <0) {
  perror("pthread_setaffinity_np");
 }
 /* waste some more time to see the processor switch */
 printf("result: %f\n", waste_time(2000));
 return 0;
}
int main(int argc, char *argv[])
{
 pthread_t my_thread;

 if (pthread_create(&my_thread, NULL, thread_func,
 NULL) != 0) {
  perror("pthread_create");
 }
 //pthread_exit(NULL);
 pthread_join(my_thread, NULL);
 return 0;

}


Compile

$ gcc -o cpu_affinity_thread cpu_affinity_thread.c  -lm -lpthread

./cpu_affinity_thread


결과화면



다른 CPU Core를 사용하는 것을 확연히 볼 수 있습니다.

.by rocksea


'Developer' 카테고리의 다른 글

[nodejs] express session 설정.  (1) 2014.03.12
[IDL] Thrift 설치.  (0) 2014.03.11
[i/o] Level Trigger, Edge Trigger  (0) 2014.02.13
[Oracle] Character set 변경.  (6) 2014.02.11
[ORACLE] user 생성 및 권한 부여.  (0) 2014.02.07
댓글