~ubuntu-branches/ubuntu/precise/hardinfo/precise

« back to all changes in this revision

Viewing changes to benchmark.c

  • Committer: Bazaar Package Importer
  • Author(s): Agney Lopes Roth Ferraz
  • Date: 2009-03-28 22:55:02 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090328225502-p4bnvi8q6hr95cij
Tags: 0.5c-1
New upstream version. 
(Closes: #517591, #511237, #457703, #519256, #449250, #457820, #497758) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *    HardInfo - Displays System Information
3
 
 *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@linuxmag.com.br>
 
3
 *    Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
4
4
 *
5
5
 *    This program is free software; you can redistribute it and/or modify
6
6
 *    it under the terms of the GNU General Public License as published by
26
26
#include <sys/resource.h>
27
27
 
28
28
enum {
29
 
    BENCHMARK_ZLIB,
 
29
    BENCHMARK_BLOWFISH,
 
30
    BENCHMARK_CRYPTOHASH,
30
31
    BENCHMARK_FIB,
31
 
    BENCHMARK_MD5,
32
 
    BENCHMARK_SHA1,
33
 
    BENCHMARK_BLOWFISH,
 
32
    BENCHMARK_NQUEENS,
 
33
    BENCHMARK_FFT,
34
34
    BENCHMARK_RAYTRACE,
35
35
    BENCHMARK_N_ENTRIES
36
36
} Entries;
37
37
 
38
 
void scan_zlib(gboolean reload);
 
38
void scan_fft(gboolean reload);
39
39
void scan_raytr(gboolean reload);
40
40
void scan_bfsh(gboolean reload);
41
 
void scan_md5(gboolean reload);
 
41
void scan_cryptohash(gboolean reload);
42
42
void scan_fib(gboolean reload);
43
 
void scan_sha1(gboolean reload);
 
43
void scan_nqueens(gboolean reload);
44
44
 
45
 
gchar *callback_zlib();
 
45
gchar *callback_fft();
46
46
gchar *callback_raytr();
47
47
gchar *callback_bfsh();
48
 
gchar *callback_md5();
49
48
gchar *callback_fib();
50
 
gchar *callback_sha1();
 
49
gchar *callback_cryptohash();
 
50
gchar *callback_nqueens();
51
51
 
52
52
static ModuleEntry entries[] = {
53
 
    {"CPU ZLib", "compress.png", callback_zlib, scan_zlib},
54
 
    {"CPU Fibonacci", "module.png", callback_fib, scan_fib},
55
 
    {"CPU MD5", "module.png", callback_md5, scan_md5},
56
 
    {"CPU SHA1", "module.png", callback_sha1, scan_sha1},
57
53
    {"CPU Blowfish", "blowfish.png", callback_bfsh, scan_bfsh},
 
54
    {"CPU CryptoHash", "cryptohash.png", callback_cryptohash, scan_cryptohash},
 
55
    {"CPU Fibonacci", "nautilus.png", callback_fib, scan_fib},
 
56
    {"CPU N-Queens", "nqueens.png", callback_nqueens, scan_nqueens},
 
57
    {"FPU FFT", "fft.png", callback_fft, scan_fft},
58
58
    {"FPU Raytracing", "raytrace.png", callback_raytr, scan_raytr},
59
59
    {NULL}
60
60
};
61
61
 
 
62
typedef struct _ParallelBenchTask ParallelBenchTask;
 
63
 
 
64
struct _ParallelBenchTask {
 
65
    guint       start, end;
 
66
    gpointer    data, callback;
 
67
};
 
68
 
 
69
gpointer benchmark_parallel_for_dispatcher(gpointer data)
 
70
{
 
71
    ParallelBenchTask   *pbt = (ParallelBenchTask *)data;
 
72
    gpointer            (*callback)(unsigned int start, unsigned int end, void *data);
 
73
    gpointer            return_value;
 
74
    
 
75
    if ((callback = pbt->callback)) {
 
76
        DEBUG("this is thread %p; items %d -> %d, data %p", g_thread_self(),
 
77
              pbt->start, pbt->end, pbt->data);
 
78
        return_value = callback(pbt->start, pbt->end, pbt->data);
 
79
        DEBUG("this is thread %p; return value is %p", g_thread_self(), return_value);
 
80
    } else {
 
81
        DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self());
 
82
    }
 
83
    
 
84
    g_free(pbt);
 
85
    
 
86
    return return_value;
 
87
}
 
88
 
 
89
gdouble benchmark_parallel_for(guint start, guint end,
 
90
                               gpointer callback, gpointer callback_data) {
 
91
    gchar       *temp;
 
92
    guint       n_cores, iter_per_core, iter;
 
93
    gdouble     elapsed_time;
 
94
    GSList      *threads = NULL, *t;
 
95
    GTimer      *timer;
 
96
    
 
97
    timer = g_timer_new();
 
98
    
 
99
    temp = module_call_method("devices::getProcessorCount");
 
100
    n_cores = temp ? atoi(temp) : 1;
 
101
    g_free(temp);
 
102
    
 
103
    while (1) {
 
104
        iter_per_core = (end - start) / n_cores;
 
105
        
 
106
        if (iter_per_core == 0) {
 
107
          DEBUG("not enough items per core; disabling one");
 
108
          n_cores--;
 
109
        } else {
 
110
          break;
 
111
        }
 
112
    }
 
113
    
 
114
    DEBUG("processor has %d cores; processing %d elements (%d per core)",
 
115
          n_cores, (end - start), iter_per_core);
 
116
    
 
117
    g_timer_start(timer);
 
118
    for (iter = start; iter < end; iter += iter_per_core) {
 
119
        ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1);
 
120
        GThread *thread;
 
121
        
 
122
        DEBUG("launching thread %d", 1 + (iter / iter_per_core));
 
123
        
 
124
        pbt->start    = iter == 0 ? 0 : iter + 1;
 
125
        pbt->end      = iter + iter_per_core - 1;
 
126
        pbt->data     = callback_data;
 
127
        pbt->callback = callback;
 
128
        
 
129
        if (pbt->end > end)
 
130
            pbt->end = end;
 
131
        
 
132
        thread = g_thread_create((GThreadFunc) benchmark_parallel_for_dispatcher,
 
133
                                 pbt, TRUE, NULL);
 
134
        threads = g_slist_append(threads, thread);
 
135
        
 
136
        DEBUG("thread %d launched as context %p", 1 + (iter / iter_per_core), threads->data);
 
137
    }
 
138
    
 
139
    DEBUG("waiting for all threads to finish");
 
140
    for (t = threads; t; t = t->next) {
 
141
        DEBUG("waiting for thread with context %p", t->data);
 
142
        g_thread_join((GThread *)t->data);
 
143
    }
 
144
    
 
145
    g_timer_stop(timer);
 
146
    elapsed_time = g_timer_elapsed(timer, NULL);
 
147
    
 
148
    g_slist_free(threads);
 
149
    g_timer_destroy(timer);
 
150
    
 
151
    DEBUG("finishing; all threads took %f seconds to finish", elapsed_time);
 
152
    
 
153
    return elapsed_time;
 
154
}
 
155
 
62
156
static gchar *__benchmark_include_results(gdouble result,
63
157
                                          const gchar * benchmark,
64
158
                                          ShellOrderType order_type)
65
159
{
66
160
    GKeyFile *conf;
67
161
    gchar **machines;
68
 
    gchar *path, *results = g_strdup("");
 
162
    gchar *path, *results = g_strdup(""), *return_value, *processor_frequency;
69
163
    int i;
70
164
 
71
165
    conf = g_key_file_new();
72
166
 
73
 
    path =
74
 
        g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf",
75
 
                         NULL);
 
167
    path = g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf", NULL);
76
168
    if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
77
169
        DEBUG("local benchmark.conf not found, trying system-wide");
78
170
        g_free(path);
95
187
    g_free(path);
96
188
    g_key_file_free(conf);
97
189
 
98
 
    DEBUG("results = %s", results);
99
 
 
100
 
    return g_strdup_printf("[$ShellParam$]\n"
101
 
                           "Zebra=1\n"
102
 
                           "OrderType=%d\n"
103
 
                           "ViewType=3\n"
104
 
                           "[%s]\n"
105
 
                           "<i>This Machine</i>=%.3f\n"
106
 
                           "%s", order_type, benchmark, result, results);
 
190
    processor_frequency = module_call_method("devices::getProcessorFrequency");
 
191
    return_value = g_strdup_printf("[$ShellParam$]\n"
 
192
                                   "Zebra=1\n"
 
193
                                   "OrderType=%d\n"
 
194
                                   "ViewType=3\n"
 
195
                                   "ColumnTitle$Extra1=CPU Clock\n"
 
196
                                   "ColumnTitle$Progress=Results\n"
 
197
                                   "ColumnTitle$TextValue=CPU\n"
 
198
                                   "ShowColumnHeaders=true\n"
 
199
                                   "[%s]\n"
 
200
                                   "<big><b>This Machine</b></big>=%.3f|%s MHz\n"
 
201
                                   "%s", order_type, benchmark, result, processor_frequency, results);
 
202
    g_free(processor_frequency);
 
203
    return return_value;
107
204
}
108
205
 
 
206
 
 
207
 
109
208
static gchar *benchmark_include_results_reverse(gdouble result,
110
209
                                                const gchar * benchmark)
111
210
{
123
222
static gdouble bench_results[BENCHMARK_N_ENTRIES];
124
223
 
125
224
#include <arch/common/fib.h>
126
 
#include <arch/common/zlib.h>
127
 
#include <arch/common/md5.h>
128
 
#include <arch/common/sha1.h>
 
225
#include <arch/common/cryptohash.h>
129
226
#include <arch/common/blowfish.h>
130
227
#include <arch/common/raytrace.h>
131
 
 
132
 
gchar *callback_zlib()
133
 
{
134
 
    return benchmark_include_results_reverse(bench_results[BENCHMARK_ZLIB],
135
 
                                             "CPU ZLib");
 
228
#include <arch/common/nqueens.h>
 
229
#include <arch/common/fft.h>
 
230
 
 
231
gchar *callback_fft()
 
232
{
 
233
    return benchmark_include_results(bench_results[BENCHMARK_FFT],
 
234
                                     "FPU FFT");
 
235
}
 
236
 
 
237
gchar *callback_nqueens()
 
238
{
 
239
    return benchmark_include_results_reverse(bench_results[BENCHMARK_NQUEENS],
 
240
                                             "CPU N-Queens");
136
241
}
137
242
 
138
243
gchar *callback_raytr()
147
252
                                     "CPU Blowfish");
148
253
}
149
254
 
150
 
gchar *callback_md5()
 
255
gchar *callback_cryptohash()
151
256
{
152
 
    return benchmark_include_results_reverse(bench_results[BENCHMARK_MD5],
153
 
                                             "CPU MD5");
 
257
    return benchmark_include_results_reverse(bench_results[BENCHMARK_CRYPTOHASH],
 
258
                                             "CPU Cryptohash");
154
259
}
155
260
 
156
261
gchar *callback_fib()
159
264
                                     "CPU Fibonacci");
160
265
}
161
266
 
162
 
gchar *callback_sha1()
163
 
{
164
 
    return benchmark_include_results_reverse(bench_results[BENCHMARK_SHA1],
165
 
                                             "CPU SHA1");
166
 
}
167
 
 
168
267
#define RUN_WITH_HIGH_PRIORITY(fn)                      \
169
268
  do {                                                  \
170
269
    int old_priority = getpriority(PRIO_PROCESS, 0);    \
173
272
    setpriority(PRIO_PROCESS, 0, old_priority);         \
174
273
  } while (0);
175
274
 
176
 
void scan_zlib(gboolean reload)
177
 
{
178
 
    SCAN_START();
179
 
    RUN_WITH_HIGH_PRIORITY(benchmark_zlib);
 
275
void scan_fft(gboolean reload)
 
276
{
 
277
    SCAN_START();
 
278
    RUN_WITH_HIGH_PRIORITY(benchmark_fft);
 
279
    SCAN_END();
 
280
}
 
281
 
 
282
void scan_nqueens(gboolean reload)
 
283
{
 
284
    SCAN_START();
 
285
    RUN_WITH_HIGH_PRIORITY(benchmark_nqueens);
180
286
    SCAN_END();
181
287
}
182
288
 
194
300
    SCAN_END();
195
301
}
196
302
 
197
 
void scan_md5(gboolean reload)
 
303
void scan_cryptohash(gboolean reload)
198
304
{
199
305
    SCAN_START();
200
 
    RUN_WITH_HIGH_PRIORITY(benchmark_md5);
 
306
    RUN_WITH_HIGH_PRIORITY(benchmark_cryptohash);
201
307
    SCAN_END();
202
308
}
203
309
 
208
314
    SCAN_END();
209
315
}
210
316
 
211
 
void scan_sha1(gboolean reload)
212
 
{
213
 
    SCAN_START();
214
 
    RUN_WITH_HIGH_PRIORITY(benchmark_sha1);
215
 
    SCAN_END();
216
 
}
217
 
 
218
317
const gchar *hi_note_func(gint entry)
219
318
{
220
319
    switch (entry) {
221
 
    case BENCHMARK_ZLIB:
222
 
        return "Results in KiB/second. Higher is better.";
223
 
 
224
 
    case BENCHMARK_MD5:
225
 
    case BENCHMARK_SHA1:
 
320
    case BENCHMARK_CRYPTOHASH:
226
321
        return "Results in MiB/second. Higher is better.";
227
322
 
228
323
    case BENCHMARK_RAYTRACE:
229
324
    case BENCHMARK_BLOWFISH:
230
325
    case BENCHMARK_FIB:
 
326
    case BENCHMARK_NQUEENS:
231
327
        return "Results in seconds. Lower is better.";
232
328
    }
233
329
 
268
364
 
269
365
    gint i = G_N_ELEMENTS(entries) - 1;
270
366
    gchar *machine = module_call_method("devices::getProcessorName");
271
 
    gchar *param = g_strdup_printf("[param]\n"
272
 
                                   "machine=%s\n" "nbenchmarks=%d\n",
273
 
                                   machine, i);
274
 
    gchar *result = param;
275
 
 
 
367
    gchar *machineclock = module_call_method("devices::getProcessorFrequency");
 
368
    gchar *machineram = module_call_method("devices::getMemoryTotal");
 
369
    gchar *result = g_strdup_printf("[param]\n"
 
370
                                    "machine=%s\n"
 
371
                                    "machineclock=%s\n"
 
372
                                    "machineram=%s\n"
 
373
                                    "nbenchmarks=%d\n",
 
374
                                    machine,
 
375
                                    machineclock,
 
376
                                    machineram, i);
276
377
    for (; i >= 0; i--) {
277
378
        if ((scan_callback = entries[i].scan_callback)) {
278
379
            scan_callback(FALSE);
279
380
 
280
 
            result = g_strdup_printf("%s\n"
281
 
                                     "[bench%d]\n"
282
 
                                     "name=%s\n"
283
 
                                     "value=%f\n",
284
 
                                     result,
285
 
                                     i, entries[i].name, bench_results[i]);
 
381
            result = h_strdup_cprintf("[bench%d]\n"
 
382
                                      "name=%s\n"
 
383
                                      "value=%f\n",
 
384
                                      result,
 
385
                                      i, entries[i].name, bench_results[i]);
286
386
        }
287
387
    }
288
388
 
289
389
    g_free(machine);
290
 
    g_free(param);
 
390
    g_free(machineclock);
 
391
    g_free(machineram);
291
392
 
292
393
    return result;
293
394
}
310
411
    sync_manager_add_entry(&se[0]);
311
412
    sync_manager_add_entry(&se[1]);
312
413
}
 
414
 
 
415
gchar **hi_module_get_dependencies(void)
 
416
{
 
417
    static gchar *deps[] = { "devices.so", NULL };
 
418
 
 
419
    return deps;
 
420
}