-
Notifications
You must be signed in to change notification settings - Fork 0
/
thread_process_creation.c
129 lines (105 loc) · 3.92 KB
/
thread_process_creation.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h> // printf,
#include <time.h> // struct timespec, clock_gettime()
#include <stdlib.h> // malloc
#include <sys/mman.h> // mmap
#include <sys/wait.h> // wait
#include <unistd.h> // sysconf
#include <pthread.h> // threading
#include <semaphore.h> // semaphore
#include "tests.h"
#include "testutils.h"
#include "log.h"
static int log_fd;
void* thread_creation_overhead(void* voidparam)
{
clock_gettime(CLOCK_REALTIME, finish);
return NULL;
}
void measure_creation_overhead(int w_iterations, int w_drop_cache)
{
log_fd = open("performance_tester.log", O_RDWR | O_APPEND | O_CREAT | O_NONBLOCK, S_IRWXU);
log_write(log_fd, 1, "Thread & process creation overhead measurement routine init.");
printf("\nMEASURING PROCESS AND THREAD CREATION OVERHEAD\n");
start = malloc(sizeof(struct timespec));
finish = mmap(NULL, sizeof(struct timespec), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
double retProcessCached = 0.0;
for(int i = 0; i < w_iterations; i++)
{
clock_gettime(CLOCK_REALTIME, start);
if(!fork())
{
// child
clock_gettime(CLOCK_REALTIME, finish);
exit(0);
}
else
{
// parent
wait(NULL);
double total = (finish->tv_nsec - start->tv_nsec);
if(i >= (w_iterations / 5))
{
retProcessCached += total;
}
}
}
printf("\nCached\t\tmean process creation using fork() with %d samples: %f us.\n", w_iterations - (w_iterations / 5), (retProcessCached / (w_iterations - (w_iterations / 5))) / 1000.0);
if(w_drop_cache)
{
int noncache_iterations = w_iterations / 10;
double retProcessUncached = 0.0;
for(int i = 0; i < noncache_iterations; i++)
{
drop_cache();
clock_gettime(CLOCK_REALTIME, start);
if(!fork())
{
// child
clock_gettime(CLOCK_REALTIME, finish);
exit(0);
}
else
{
// parent
wait(NULL);
double total = (finish->tv_nsec - start->tv_nsec);
retProcessUncached += total;
}
}
printf("Non-cached\tmean process creation using fork() with %d samples: %f us.\n", noncache_iterations, (retProcessUncached / noncache_iterations) / 1000.0);
}
munmap(finish, sizeof(*finish));
finish = malloc(sizeof(struct timespec));
pthread_t thread_creation;
double retThreadCached = 0.0;
for(int i = 0; i < w_iterations; i++)
{
clock_gettime(CLOCK_REALTIME, start);
pthread_create(&thread_creation, NULL, thread_creation_overhead, NULL);
pthread_join(thread_creation, NULL);
double total = (finish->tv_nsec - start->tv_nsec);
if(i >= (w_iterations / 5))
{
retThreadCached += total;
}
}
printf("\nCached\t\tmean thread creation time using pthread_create() with %d samples: %f us\n", w_iterations - (w_iterations / 5), (retThreadCached / (w_iterations - (w_iterations / 5))) / 1000.0);
if(w_drop_cache)
{
double retThreadUncached = 0.0;
int noncache_iterations = w_iterations / 10;
for(int i = 0; i < noncache_iterations; i++)
{
drop_cache();
clock_gettime(CLOCK_REALTIME, start);
pthread_create(&thread_creation, NULL, thread_creation_overhead, NULL);
pthread_join(thread_creation, NULL);
double total = (finish->tv_nsec - start->tv_nsec);
retThreadUncached += total;
}
printf("Non-cached\tmean thread creation time using pthread_create() with %d samples: %f us\n", noncache_iterations, (retThreadUncached / noncache_iterations) / 1000.0);
}
close(log_fd);
free(start);
free(finish);
}