Linux binds different threads to different cores and CPUs--PTHREAD_SETAFFINITY_NP

Source: Internet
Author: User
Tags bitmask erro

===============================================================

Linux single-process multithreaded program, to achieve the average allocation of each thread to the multicore CPU, there are 2 main methods

1: Using the Linux system's own thread switching mechanism, Linux has a service called irqbalance, this service is the Linux system comes with, the default will start, the role of the service is to distribute multithreading evenly on each core of the CPU, as long as the service does not stop, Multi-threaded allocations can be implemented on their own. Note, however, that if there is a loop inside the thread function and there are no system calls within that loop, it can cause the CPU time of the thread to not be switched out. That is, the CPU is full, at this time add a system call, such as sleep, the CPU time of the thread can be switched out.

2: Use the Pthread Library's own thread affinity setting function to set the thread to run on a CPU core, which needs to be implemented inside the program. Also, be careful not to confuse the process affinity setting.

12345678910111213 intpthread_setaffinity_np(pthread_t threadsize_t cpusetsize,constcpu_set_t *cpuset);intpthread_getaffinity_np(pthread_t threadsize_tcpusetsize, cpu_set_t *cpuset);从函数名以及参数名都很明了,唯一需要点解释下的可能就是cpu_set_t这个结构体了。这个结构体的理解类似于select中的fd_set,可以理解为cpu集,也是通过约定好的宏来进行清除、设置以及判断://初始化,设为空void CPU_ZERO (cpu_set_t *set); //将某个cpu加入cpu集中 voidCPU_SET (intcpu, cpu_set_t *set); //将某个cpu从cpu集中移出 voidCPU_CLR (intcpu, cpu_set_t *set); //判断某个cpu是否已在cpu集中设置了 int CPU_ISSET (intcpu, constcpu_set_t *set);

=================================================================

Transferred from: http://blog.csdn.net/sprintfwater/article/details/39203049

To bind a thread to a different processor:

There are two CPUs, one CPU and five cores.

[HTML]View PlainCopyprint?
  1. #define  _GNU_SOURCE                                                                                                                                                      
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <sched.h>
  7. inline int set_cpu (int i)
  8. {
  9. cpu_set_t Mask;
  10. Cpu_zero (&mask);
  11. Cpu_set (I,&mask);
  12. printf ("Thread%u, i =%d\n", pthread_self (), i);
  13. if (-1 = = PTHREAD_SETAFFINITY_NP (pthread_self (), sizeof (mask), &mask))
  14. {
  15. fprintf (stderr, "pthread_setaffinity_np erro\n");
  16. return-1;
  17. }
  18. return 0;
  19. }
  20. void *thread_ip_bitmap_set (void *p)
  21. {
  22. uint32_t i, IP;
  23. struct Id_ipmap *entry;
  24. thread_info_t *info = (thread_info_t *) p;
  25. if (Set_cpu (info->id))
  26. {
  27. return NULL;
  28. }
  29. printf ("info->id =%d;  info->start =%d; info->end =%d, sub =%d\n ", info->id, info->start, info->end, info->start-  info->end);
  30. for (i = info->start; i < info->end; ++i) {
  31. entry = &ipmap_queue[i];
  32. for (IP = entry->ip_start; IP < entry->ip_end; ip++) {
  33. Ip_bitmap_set (Adns_htobe32 (IP), entry->id);
  34. }
  35. }
  36. printf ("info->id =%d finished\n", info->id);
  37. return NULL;
  38. }
  39. int main ()
  40. {
  41. For (thread_index=0; Thread_index < thread_index++)
  42. Pthread_create (&thread_id[thread_index],null, Thread_ip_bitmap_set, &thread_info[thread_index]);
  43. }

[CPP]View PlainCopyprint?
  1. #define _gnu_source
  2. #include <sched.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <pthread.h>
  9. inline int set_cpu (int i)
  10. {
  11. cpu_set_t Mask;
  12. Cpu_zero (&mask);
  13. Cpu_set (I,&mask);
  14. printf ("thread%u, i =%d\n", pthread_self (), i);
  15. if ( -1 = = PTHREAD_SETAFFINITY_NP (Pthread_self (),sizeof (mask), &mask))
  16. {
  17. return-1;
  18. }
  19. return 0;
  20. }
  21. void *fun (void *i)
  22. {
  23. if (set_cpu (* (int *) i))
  24. {
  25. printf ("Set CPU erro\n");
  26. }
  27. a long long a = 0;
  28. While (1)
  29. {
  30. A + = rand ();
  31. }
  32. return NULL;
  33. }
  34. int main (int argc, const char * argv[]) {
  35. int i;
  36. int cpu_nums = sysconf (_sc_nprocessors_conf);
  37. printf ("cpu_numbs =%d\n", cpu_nums);
  38. pthread_t THREAD[10];
  39. int tmp[10];
  40. For (i = 0; i <; ++i)
  41. {
  42. Tmp[i] = i;
  43. Pthread_create (&thread[i],null,fun, &tmp[i]);
  44. }
  45. For (i = 0; i <; ++i)
  46. {
  47. Pthread_join (Thread[i],null);
  48. }
  49. return 0;
  50. }

Reprint: http://blog.csdn.net/xluren/article/details/43202201

Coolshell's latest article, "Performance Tuning Strategy", in the "Multicore CPU Tuning" section, mentions that "we can't load balance the operating system because we know our own programs better, so we can manually allocate CPU cores for them without too much CPU0." or let our critical processes and a bunch of other processes squeeze together. ”。 The article mentions a tool under Linux, Taskset, which can set the CPU for a single process to run.

At the same time, because of the recent data on Redis, Redis is a single-process model that, in order to take full advantage of multicore CPUs, often launches multiple instances on one server. To reduce the overhead of switching, it is necessary to specify the CPU on which each instance runs.

The following describes the Taskset command and the sched_setaffinity system call, both of which can specify the CPU instances that the process runs.

1.taskset

Taskset is a command provided by Linux (Ubuntu system may need to install itself, Schedutils package). He can have a program run on some (or) of the CPUs.

The following are examples of redis-server.

1) shows the CPU the process is running on

Command Taskset-p 21184

Show Results:

PID 21184 ' s current affinity mask:ffffff

Note: 21184 is redis-server running PID

The ffffff of the result is actually a binary 24 low 1 bitmask, each 1 corresponds to 1 CPUs, indicating that the process runs on 24 CPUs

2) Specify that the process is running on a specific CPU

Command TASKSET-PC 3 21184

Show Results:

PID 21184 ' s current affinity list:0-23
PID 21184 ' s new affinity List:3

Note: 3 means that the CPU will only run on the 4th CPU (counting from 0).

3) Specify CPU when process starts

Command taskset-c 1./redis-server. /redis.conf

Combined with the above three examples, and then look at the Taskset manual, it is more clear.

OPTIONS
-P,--pid
operate on the existing PID and not launch a new task

-C,--cpu-list
Specify a numerical list of processors instead of a bitmask. The list may contain multiple items, separated by comma, and ranges. For example, 0,5,7,9-11.

2.sched_setaffinity system Call

The following article is partly translated from: http://www.thinkingparallel.com/2006/08/18/more-information-on-pthread_setaffinity_np-and-sched_setaffinity/

Problem description

Sched_setaffinity can bind a process to a specific CPU. You know your program better than the operating system, and you might want to do this to avoid the scheduler's foolish scheduling of your programs, or to avoid the overhead of caching failures in multithreaded programs. The following is an example of sched_setaffinity, whose function manual can be consulted (http://www.linuxmanpages.com/man2/sched_getaffinity.2.php):

 1/* Short test program to test sched_setaffinity 2 * (which sets the affinity of processes to processors). 3 * COMPILE:GCC sched_setaffinity_test.c 4 *             -O sched_setaffinity_test-l M 5 * Usage:./sched_setaffinity_test 6 * 7 * Open a "top"-window at the same time and see all the work 8 * being do on CPU 0 First and after a short wait on CPU 1. 9 * Repeat with different numbers to make sure, it's not A10 * coincidence.11 */12  13 #include <stdio.h>14 #i Nclude <math.h>15 #include <sched.h>16  17 double waste_time (long N) * {    Double res = 0;2 0     Long i = 0;21     while (i <n * 200000) {$         i++;23     & nbsp    Res + = sqrt (i),    }25     return res;26}27  28 int main (int argc, char **argv) 29 {30     unsigned long mask = 1; /* Processor 0 */31  32    /* bind process to processor 0 */33     if (sched_setaffinity (0, sizeof (mask), &mask) <0) {$         perror ("s Ched_setaffinity ")    }36  37    /* Waste some time so the work is visible with" top "*/38 & nbsp   printf ("Result:%f\n", Waste_time),  40     mask = 2; /* Process switches to processor 1 now */41     if (sched_setaffinity (0, sizeof (mask), &mask) <0) {&NB Sp       perror ("sched_setaffinity"),    }44  45    /* Waste some more time to SE E The processor switch */46     printf ("Result:%f\n", Waste_time (2000)); 47}

Adjust the waste_time parameters according to the speed of your CPU. You can then use the top command to see the process switching between different CPUs. (press "1" after starting the top command to see the individual CPUs).

The settings for affinity are inherited between the parent and child processes. So, with a bold guess, Taskset is actually first executing the sched_setaffinity system call and then fork+exec the user-specified process.

Linux binds different threads to different cores and CPUs--PTHREAD_SETAFFINITY_NP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.