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
|
/*****************************************************************************
*
* memload - a simple tool to test memory allocator speed
*
* Copyright (C) 2011 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include "allocer.hh"
long simple_test() {
Allocer a(17, 1000);
const long iterations = 1000000;
for(long i=0; i<iterations; i++) {
a.allocate();
}
return iterations;
}
long multiple_test() {
std::vector<Allocer*> allocs;
const int num_allocs = 10;
const int num_iterations = 10000000;
// Change these two lines to test different allocation strategies.
unsigned int alloc_sizes[] = {1, 2, 5, 8, 17, 22, 30, 42, 54, 88, 1024};
unsigned int max_sizes[] = {200000, 100000, 50000, 50000, 40000, 40000, 40000, 30000, 30000, 20000, 1000};
for(int i=0; i<num_allocs; i++) {
allocs.push_back(new Allocer(alloc_sizes[i], max_sizes[i]));
}
for(long iterations=0; iterations<num_iterations; iterations++) {
int index = random() % allocs.size();
allocs[index]->allocate();
}
for(int i=0; i<num_allocs; i++) {
delete(allocs[i]);
}
allocs.clear();
return num_iterations;
}
void* thread_wrapper(void *iterations) {
*(reinterpret_cast<long*>(iterations)) = multiple_test();
return NULL;
}
long thread_test() {
const int NUM_THREADS = 10;
pthread_t threads[NUM_THREADS];
long counts[NUM_THREADS];
volatile long *results;
long total = 0;
results = counts;
for(int i=0; i<NUM_THREADS; i++) {
int rc;
rc = pthread_create(&threads[i], NULL, thread_wrapper, &counts[i]);
if (rc != 0)
throw strerror(rc);
}
for(int i=0; i<NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
for(int i=0; i<NUM_THREADS; i++) {
total += results[i];
}
return total;
}
int main(int argc, char **argv) {
long iterations;
struct timeval start;
struct timeval end;
double start_sec, end_sec, total_time;
double throughput;
gettimeofday(&start, NULL);
try {
//iterations = simple_test();
//iterations = multiple_test();
iterations = thread_test();
} catch(char const* msg) {
printf("%s\n", msg);
return 1;
}
gettimeofday(&end, NULL);
start_sec = start.tv_sec + start.tv_usec * 1e-6;
end_sec = end.tv_sec + end.tv_usec * 1e-6;
total_time = end_sec - start_sec;
throughput = iterations / total_time;
printf("%ld allocations in %f seconds, %f allocs/s.\n", iterations, total_time, throughput);
return 0;
}
|