~jpakkane/+junk/memload

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;
}