Find the answer to your Linux question:
Results 1 to 8 of 8
Hi folks. I am trying to optimize the performance for a multi-(POSIX)thread application running on a multi-processor platform. Each processor is multi-core, as in most modern architectures, and has L1 ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Sep 2013
    Posts
    12

    [C programming] binding POSIX threads to a specific processor core.


    Hi folks.

    I am trying to optimize the performance for a multi-(POSIX)thread application running on a multi-processor platform. Each processor is multi-core, as in most modern architectures, and has L1 and L2 caches specific to each core and a L3 shared among all the cores in a processor.

    Keeping the data in the cache as much as possible is vital. So I am trying to bind threads 0 to 7 to cores 0 to 7 in processor 0, threads 8 to 15 to cores 0 to 7 in processor 1, etc.

    I have found the sched_setaffinity() / sched_get_affinity() functions that bind a thread to a processor, not to a core. So, my question is: is there a way to bind a specific thread to a specific core inside a processor?

    Thanks

    Stefano

  2. #2
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,444
    I haven't bothered with this cruft since the days of single core / multiple processor systems almost 10 years ago. Since the system basically sees each core as a processor, then you should still be able to "bind" a bit of code to a specific core, but I'm not sure precisely how to do that since you have found that the set/get affinity methods only apply to a processor and not a core.

    So, after some very cursory man page reading, since this is thread-specific, have you tried using pthread_setaffinity_np(), etc?
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  3. #3
    Just Joined!
    Join Date
    Sep 2013
    Posts
    12
    To the best of my knowledge, the pthread_setaffinity_np() binds a thread to a processor (not to a core) exactly as sched_setaffinity().

  4. #4
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,444
    Quote Originally Posted by stefano913 View Post
    To the best of my knowledge, the pthread_setaffinity_np() binds a thread to a processor (not to a core) exactly as sched_setaffinity().
    Sample code from the pthread_setaffinity_np man page (implies that cores are == processor):
    Code:
           In the following program, the main thread uses pthread_setaffinity_np() to set its CPU affinity mask to include CPUs 0 to
           7 (which may not all be available on the system), and then calls pthread_getaffinity_np()  to  check  the  resulting  CPU
           affinity mask of the thread.
    
           #define _GNU_SOURCE
           #include <pthread.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <errno.h>
    
           #define handle_error_en(en, msg) \
                   do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
    
           int
           main(int argc, char *argv[])
           {
               int s, j;
               cpu_set_t cpuset;
               pthread_t thread;
    
               thread = pthread_self();
    
               /* Set affinity mask to include CPUs 0 to 7 */
    
               CPU_ZERO(&cpuset);
               for (j = 0; j < 8; j++)
                   CPU_SET(j, &cpuset);
    
               s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
               if (s != 0)
                   handle_error_en(s, "pthread_setaffinity_np");
    
               /* Check the actual affinity mask assigned to the thread */
    
               s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
               if (s != 0)
                   handle_error_en(s, "pthread_getaffinity_np");
    
               printf("Set returned by pthread_getaffinity_np() contained:\n");
               for (j = 0; j < CPU_SETSIZE; j++)
                   if (CPU_ISSET(j, &cpuset))
                       printf("    CPU %d\n", j);
    
               exit(EXIT_SUCCESS);
           }
    Don't know if this helps...
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  5. #5
    Just Joined!
    Join Date
    Sep 2013
    Posts
    12
    I compiled and ran the example code you pasted:

    Code:
    stefano@frankenstein:~/Desktop$ gcc proc.c -lpthread
    stefano@frankenstein:~/Desktop$ ./a.out 
    Set returned by pthread_getaffinity_np() contained:
        CPU 0
        CPU 1
        CPU 2
        CPU 3
    and from the output of this command

    Code:
    stefano@frankenstein:~/Desktop$ lscpu
    Architecture:          i686
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                4
    On-line CPU(s) list:   0-3
    Thread(s) per core:    2
    Core(s) per socket:    2
    Socket(s):             1
    Vendor ID:             GenuineIntel
    CPU family:            6
    Model:                 42
    Stepping:              7
    CPU MHz:               800.000
    BogoMIPS:              5587.33
    Virtualisation:        VT-x
    L1d cache:             32K
    L1i cache:             32K
    L2 cache:              256K
    L3 cache:              4096K
    it seems that it's assigning the thread to a set of processors: the system has 4 dual-core processors.

  6. #6
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,444
    Ok. Out of ideas now... You might want to post this question to www.kernel.org.
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  7. #7
    Just Joined!
    Join Date
    Sep 2013
    Posts
    12
    Will do. Thanks a lot Rubberman.

  8. #8
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, in Chicago, or in a galaxy far, far away.
    Posts
    11,444
    Let us know how this works out for you. It may help others!
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •