[Ubuntu 14.04] Setting process affinity in kernel mode (2/2 – Example code)

Standard

Prerequisite)
Prerequisite and all steps from https://study.prl85.com/ubuntu-14-04-setting-process-affinity-in-kernel-mode-12-kernel-modification

Sample code (cpu_affinity_user.c)

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sched.h>
#include <errno.h>
#include <linux/unistd.h>

void printCoreList()
{
	int i = 0;
	
	pid_t p = 0;	// meaning current process
	cpu_set_t mask;
	size_t len = sizeof(cpu_set_t);

	printf("(Current available CPU Core ID List:");	
	sched_getaffinity(p, len, &mask); // get available (movable) cpu cores

	bool printed = false;
	for (i = 0; i<CPU_SETSIZE; i++) 
	{
		if (CPU_ISSET(i, &mask))
		{
			printed = true;
			printf(" %d", i);
		}
	}
	
	if (printed == false)
		printf(" None");
	printf(")\n");
}

double measureTime(int calledID)
{
//	printf("Work - Called from cpu core %d\n", calledID);
	printf("Work - My allocated cpu core is %d\n", sched_getcpu());
		
	struct timeval currenttime;
	int i;
	
	// measure start time
	gettimeofday( &currenttime, 0 );

	long cur_time1 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec1 = cur_time1 / 1000000.0;
	
	// do some work
	for(i = 0; i < 5000000; i++)
		printf("%s", "\r");

	// measure end time
	gettimeofday( &currenttime, 0 );

	long cur_time2 = 1000000 * currenttime.tv_sec + currenttime.tv_usec;
	double sec2 = cur_time2 / 1000000.0;
	
	return sec2 - sec1;
}

int main()
{
	srand(time(NULL));

	int i = 0, j = 0, cpuChanged = 0;

	pid_t p = 0;	// meaning current process
	size_t len = sizeof(cpu_set_t);
	cpu_set_t new_mask;

	int numCpuCore = get_nprocs();		// get total number of cpu core
	int currentCore;	

	printf("Total number of CPU Core: %d\n", numCpuCore);
	printf("Current allocated CPU Core ID: %d\n", currentCore = sched_getcpu());	// get current allocated core

//	printCoreList(); // uncomment to see cpu affinity
	
	// case 1: normal mode (no cpu core fix)
	printf("<Doing some work without fixing the cpu core...>\n\n");

	int numOfRepetition = 30; // number of task repetition
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);
	
	// case 2: special mode (cpu core fix)
	printf("\n<Randomly assigning another core...>\n");
	while(1)
	{
		int newcpuID = rand() % numCpuCore;
		if (newcpuID != currentCore)
		{
			CPU_ZERO(&new_mask);
			CPU_SET(newcpuID, &new_mask);
			break;
		}
	}
	
	cpuChanged = 0;
	
	// set to new core
	sched_setaffinity(p, len, &new_mask);
	printf("<New allocated CPU Core ID: %d>\n", sched_getcpu());
	
	printf("<Doing some work after fixing the cpu core...>\n");
	
	for (i = 0; i < numOfRepetition; i++) 
	{
		printf("[%3d/%3d] ", i+1, numOfRepetition);
		double elapsedTime = measureTime(currentCore = sched_getcpu());	// do work

		int newCore = sched_getcpu();	// what is current core after work?
		if (currentCore != newCore) // if the allocated cpu core is changed 
		{
			printf(" After work, my allocated CPU Core ID is moved to %d\n", currentCore = newCore);	
			cpuChanged++;
		}
	}
	printf("* Number of CPU core allocation change: %d (Out of %d trials, %.1lf%%)*\n", cpuChanged, numOfRepetition, (double) cpuChanged/(double) numOfRepetition*100.0);	
	return 0;
}

This code will execute measureTime() 30 times without cpu core fixed, then 30 times with cpu core fixed.
Each measureTime() takes some time, possibility of core allocation change, as shown in result.

How to run)

gcc cpu_affinity_user.c -o affinitytest
./affinitytest

Result)

Part 1 – CPU Core information, and initial allocated core

Total number of CPU Core: 4
Current allocated CPU Core ID: 1
(Current available CPU Core ID List: 0 1 2 3)

Part 2 – CPU core movement before fixing the cpu core

<Doing some work without fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  2/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[  3/ 30] Work - My allocated cpu core is 1
[  4/ 30] Work - My allocated cpu core is 1
 After work, my allocated CPU Core ID is moved to 0
[  5/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[  6/ 30] Work - My allocated cpu core is 3
[  7/ 30] Work - My allocated cpu core is 3
[  8/ 30] Work - My allocated cpu core is 3
[  9/ 30] Work - My allocated cpu core is 3
[ 10/ 30] Work - My allocated cpu core is 3
[ 11/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 2
[ 12/ 30] Work - My allocated cpu core is 2
 After work, my allocated CPU Core ID is moved to 3
[ 13/ 30] Work - My allocated cpu core is 3
[ 14/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 21/ 30] Work - My allocated cpu core is 3
[ 22/ 30] Work - My allocated cpu core is 3
[ 23/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 3
[ 27/ 30] Work - My allocated cpu core is 3
[ 28/ 30] Work - My allocated cpu core is 3
 After work, my allocated CPU Core ID is moved to 0
[ 29/ 30] Work - My allocated cpu core is 0
 After work, my allocated CPU Core ID is moved to 1
[ 30/ 30] Work - My allocated cpu core is 1
* Number of CPU core allocation change: 12 (Out of 30 trials, 40.0%)*

Part 3 – CPU core movement after fixing the cpu core

<Randomly assigning another core...>
<New allocated CPU Core ID: 0>
<Doing some work after fixing the cpu core...>
[  1/ 30] Work - My allocated cpu core is 0
[  2/ 30] Work - My allocated cpu core is 0
[  3/ 30] Work - My allocated cpu core is 0
[  4/ 30] Work - My allocated cpu core is 0
[  5/ 30] Work - My allocated cpu core is 0
[  6/ 30] Work - My allocated cpu core is 0
[  7/ 30] Work - My allocated cpu core is 0
[  8/ 30] Work - My allocated cpu core is 0
[  9/ 30] Work - My allocated cpu core is 0
[ 10/ 30] Work - My allocated cpu core is 0
[ 11/ 30] Work - My allocated cpu core is 0
[ 12/ 30] Work - My allocated cpu core is 0
[ 13/ 30] Work - My allocated cpu core is 0
[ 14/ 30] Work - My allocated cpu core is 0
[ 15/ 30] Work - My allocated cpu core is 0
[ 16/ 30] Work - My allocated cpu core is 0
[ 17/ 30] Work - My allocated cpu core is 0
[ 18/ 30] Work - My allocated cpu core is 0
[ 19/ 30] Work - My allocated cpu core is 0
[ 20/ 30] Work - My allocated cpu core is 0
[ 21/ 30] Work - My allocated cpu core is 0
[ 22/ 30] Work - My allocated cpu core is 0
[ 23/ 30] Work - My allocated cpu core is 0
[ 24/ 30] Work - My allocated cpu core is 0
[ 25/ 30] Work - My allocated cpu core is 0
[ 26/ 30] Work - My allocated cpu core is 0
[ 27/ 30] Work - My allocated cpu core is 0
[ 28/ 30] Work - My allocated cpu core is 0
[ 29/ 30] Work - My allocated cpu core is 0
[ 30/ 30] Work - My allocated cpu core is 0
* Number of CPU core allocation change: 0 (Out of 30 trials, 0.0%)*

 

Leave a Reply

Your email address will not be published. Required fields are marked *