This is a small Linux SMP programming tip, which I had a hard time finding documented clearly anywhere on the web. I guess people won’t find it here either, but with some luck some search engine will pick up on this.
Basically, the problem I faced was that the Linux scheduler (in the MPC8641D setup Linux 2.6.23 setup that I have blogged about before — here and here) executed my test program on cpu zero and cpu one depending on its input parameters in a way that really made performance measurements give strange results. For some reason, certain input values almost always put the program on cpu one, and others on cpu zero. Very consistently, and I cannot understand what in the difference between a “119” and a “120” on a command-line makes the Linux scheduler make a different decision on the best processor on which to put a certain execution of my program.
The solution was to revisit the ability of Linux to tie processes to certain cores in the system, something that I was not actually sure existed. But it did, and apparently for most of the 2.6 kernel at least. One thing that threw me off for a short while was that the feature had to be accessed through the user-level calls in glibc, which meant that my scavenging through the kernel source was pretty useless.
Anyway, here is the code I came up with. Defining USE_GNU was necessary to allow the function to be accessed, since this is Linux-specific.
#define __USE_GNU #include void tie_program_to_cpu_0(void) { cpu_set_t my_affinity_set; CPU_ZERO(&my_affinity_set); // no CPUs set CPU_SET(0, &my_affinity_set); // set cpu0 sched_setaffinity(0, // 0=current process sizeof(cpu_set_t), &my_affinity_set); printf(" Tying program to run only on CPU0 using sched_setaffinity()\n"); }
Tested with:
- Linux 2.6.23 for powerpc architecture (Freescale MPC8641D HPCN board support package from Freescale LTIB)
- gcc version 4.1.2 (Code Sourcery G++ Lite 4.1-78), with its accompanying glibc