How to use sched_getaffinity and sched_setaffinity in Linux from C?

后端 未结 3 478
清歌不尽
清歌不尽 2020-12-03 05:29

I am trying to:

  • Run 16 copies concurrently with processor pinning (2 copies per core)

  • Run 8 copies concurrently with processor pinning (2 co

3条回答
  •  感动是毒
    2020-12-03 06:11

    Minimal runnable example

    In this example, we get the affinity, modify it, and check if it has taken effect with sched_getcpu().

    main.c

    #define _GNU_SOURCE
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    void print_affinity() {
        cpu_set_t mask;
        long nproc, i;
    
        if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
            perror("sched_getaffinity");
            assert(false);
        }
        nproc = sysconf(_SC_NPROCESSORS_ONLN);
        printf("sched_getaffinity = ");
        for (i = 0; i < nproc; i++) {
            printf("%d ", CPU_ISSET(i, &mask));
        }
        printf("\n");
    }
    
    int main(void) {
        cpu_set_t mask;
    
        print_affinity();
        printf("sched_getcpu = %d\n", sched_getcpu());
        CPU_ZERO(&mask);
        CPU_SET(0, &mask);
        if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
            perror("sched_setaffinity");
            assert(false);
        }
        print_affinity();
        /* TODO is it guaranteed to have taken effect already? Always worked on my tests. */
        printf("sched_getcpu = %d\n", sched_getcpu());
        return EXIT_SUCCESS;
    }
    

    GitHub upstream.

    Compile and run:

    gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
    ./main.out
    

    Sample output:

    sched_getaffinity = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
    sched_getcpu = 9
    sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    sched_getcpu = 0
    

    Which means that:

    • initially, all of my 16 cores were enabled, and the process was randomly running on core 9 (the 10th one)
    • after we set the affinity to only the first core, the process was moved necessarily to core 0 (the first one)

    It is also fun to run this program through taskset:

    taskset -c 1,3 ./a.out
    

    Which gives output of form:

    sched_getaffinity = 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
    sched_getcpu = 2
    sched_getaffinity = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
    sched_getcpu = 0
    

    and so we see that it limited the affinity from the start.

    This works because the affinity is inherited by child processes, which taskset is forking: How to prevent inheriting CPU affinity by child forked process?

    nproc respects sched_getaffinity by default as shown at: How to find out the number of CPUs using python

    Python: os.sched_getaffinity and os.sched_setaffinity

    See: How to find out the number of CPUs using python

    Tested in Ubuntu 16.04.

提交回复
热议问题