1// Mini-benchmark for creating a lot of threads. 2// 3// Some facts: 4// a) clang -O1 takes <15ms to start N=500 threads, 5// consuming ~4MB more RAM than N=1. 6// b) clang -O1 -ftsan takes ~26s to start N=500 threads, 7// eats 5GB more RAM than N=1 (which is somewhat expected but still a lot) 8// but then it consumes ~4GB of extra memory when the threads shut down! 9// (definitely not in the barrier_wait interceptor) 10// Also, it takes 26s to run with N=500 vs just 1.1s to run with N=1. 11#include <assert.h> 12#include <pthread.h> 13#include <stdio.h> 14#include <stdlib.h> 15#include <unistd.h> 16 17pthread_barrier_t all_threads_ready; 18 19void* Thread(void *unused) { 20 pthread_barrier_wait(&all_threads_ready); 21 return 0; 22} 23 24int main(int argc, char **argv) { 25 int n_threads; 26 if (argc == 1) { 27 n_threads = 100; 28 } else if (argc == 2) { 29 n_threads = atoi(argv[1]); 30 } else { 31 printf("Usage: %s n_threads\n", argv[0]); 32 return 1; 33 } 34 printf("%s: n_threads=%d\n", __FILE__, n_threads); 35 36 pthread_barrier_init(&all_threads_ready, NULL, n_threads + 1); 37 38 pthread_t *t = new pthread_t[n_threads]; 39 for (int i = 0; i < n_threads; i++) { 40 int status = pthread_create(&t[i], 0, Thread, (void*)i); 41 assert(status == 0); 42 } 43 // sleep(5); // FIXME: simplify measuring the memory usage. 44 pthread_barrier_wait(&all_threads_ready); 45 for (int i = 0; i < n_threads; i++) { 46 pthread_join(t[i], 0); 47 } 48 // sleep(5); // FIXME: simplify measuring the memory usage. 49 delete [] t; 50 51 return 0; 52} 53