How to set CPU Affinities on linux box:


#include <cstdio>
#include <errno.h>
#include <sched.h>

#include <unistd.h> //processor affinity.
#include <sys/syscall.h> // thread ID.
#include <sys/resource.h> // get/set priority.

using namespace std;

int ShowAffinity () {
     cpu_set_t *mask;
     size_t size;

     // you can use sysconf or __CPU_SETSIZE system macro.
     int ncpu = sysconf(_SC_NPROCESSORS_ONLN);

     mask = CPU_ALLOC(ncpu);
     size = CPU_ALLOC_SIZE(ncpu);
     CPU_ZERO_S(size, mask);
     errno = 0;
     if ( sched_getaffinity(0, sizeof(mask), mask) == -1 ) {
     CPU_FREE(mask);
     switch ( errno ) {
     case EPERM: printf ( “Error: Insufficient permission.\n” ); break;
     case EFAULT: printf ( “Error: Invalid memory address.\n” ); break;
     case ESRCH: printf ( “Error: Invalid process ID\n” ); break;
     case EINVAL: printf ( “Error: Invalid arguments\n” ); break;
     }
     return -1;
     }

     printf ( “CPU Affinity: \n” );
     for ( int i=0; i < ncpu; i ++ ) {
         if ( CPU_ISSET_S( i, size, mask ) ) {
            printf(“\tCPU %d is set\n”, (i+1));
         }
     }

     CPU_FREE(mask);
    return 0;
}

int SetAffinity ( int cpuId ) {
    int ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    cpu_set_t *mask = CPU_ALLOC(ncpu);
    size_t size = CPU_ALLOC_SIZE(ncpu);
    CPU_ZERO_S(size, mask);
    CPU_SET_S(cpuId, size, mask);
    if ( sched_setaffinity(0, size, mask) == -1 ) {
       CPU_FREE(mask);
       switch ( errno ) {
       case EPERM: printf ( “Error: Insufficient permission.\n” ); break;
       case EFAULT: printf ( “Error: Invalid memory address.\n” ); break;
       case ESRCH: printf ( “Error: Invalid process ID\n” ); break;
       case EINVAL: printf ( “Error: Invalid arguments\n” ); break;
       }
       return -1;
    }

    CPU_FREE(mask);
    return 0;
}

int ResetAffinity () {
    int ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    cpu_set_t *mask = CPU_ALLOC(ncpu);
    size_t size = CPU_ALLOC_SIZE(ncpu);

    CPU_ZERO_S(size, mask);
    for ( int i=0; i < ncpu; i++ ) {
        CPU_SET_S(i, size, mask);
    }

    if ( sched_setaffinity(0, size, mask) == -1 ) {
        CPU_FREE(mask);
        switch ( errno ) {
        case EPERM: printf ( “Error: Insufficient permission.\n” ); break;
        case EFAULT: printf ( “Error: Invalid memory address.\n” ); break;
        case ESRCH: printf ( “Error: Invalid process ID\n” ); break;
        case EINVAL: printf ( “Error: Invalid arguments\n” ); break;
        default: printf ( “Error: Unexpected Error code %d\n”, errno ); break;
        }
        return -1;
    }

    CPU_FREE(mask);
    return 0;
}

 

// To set CPU affinity of a any thread, call  SetAffinity() from thread function.

// e.g. you can set affinity for main thread/process as follows:

int main(void) {

    //get number of processors on the box.
    int ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    ShowAffinity ();
    printf ( “\nRestricting to only middle one : %d \n”, ncpu/2 );
    SetAffinity ( (ncpu-1) / 2 );
    ShowAffinity ();

    return 0;
}

Advertisements

Tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: