I am working on a C program to generate graphs to do with Ramsey Theory, and I'm currently refining my multithreading performance. At some point I decided to just do a sanity check and make sure that my multi-threaded implementation, when told to run with only 1 thread, is at least not slower than my original implementation.
It turns out it was running about 50% slower. A lot of trial and error later I managed to get it to the following state:
void * blah(){
printf("Hello, this is thread\n");
}
void clean(){
//Set up function
pthread_t tid;
pthread_create(&tid, NULL, blah, NULL);
//Do computationally expensive stuff in the current thread
}
As shown above, the program takes 42 seconds with the first data set, and 767 with the other. If I comment out the pthread_create call, the same exact program processes the first data set in 30 seconds and the second in 528 seconds.
I've tried looking for solutions and found a lot of great answers to do with false sharing and cache thrashing etc. When running the multithreaded version with 2, 3, or 4 threads I do see that each further thread runs a little slower, but what I cannot understand is why spawning even a single unrelated thread kills performance so much.
Even spawning a dozen copies of the same blah thread in this reduced case results in the exact same performance penalty. I even tried again without the -O3 compile flag and the same proportional slowdown was there, albeit a little less extreme. The only thing that might have to do with it that I haven't tried yet is to compile and run on a different system.
Any clues would be greatly appreciated.
Edit:
After taking into account the suggestions from the comments, it appears I have found the problem. @ninjalj suggested that it might be to do with malloc locks, so I wrote the following test code that runs in 19 seconds without the call to pthread_create, and 32 seconds with it, at least on my machine.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#define CALLS 10000
void * dummy(void * args){
printf("Hello, this is thread\n");
}
int main(int argc, char ** argv){
pthread_t tid;
pthread_create(&tid, NULL, dummy, NULL);
time_t start, end;
start = time(NULL);
int * memory;
for(int i = 0; i < CALLS*10; i ++){
for(int j = 0; j < CALLS; j++){
memory = malloc(10);
free(memory);
}
}
end = time(NULL);
printf("That took %d s\n", end - start);
}