diff options
Diffstat (limited to 'benchmark.c')
-rw-r--r-- | benchmark.c | 250 |
1 files changed, 179 insertions, 71 deletions
diff --git a/benchmark.c b/benchmark.c index 3c6f0f1f..8bbfe11a 100644 --- a/benchmark.c +++ b/benchmark.c @@ -1,6 +1,6 @@ /* * HardInfo - Displays System Information - * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@linuxmag.com.br> + * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org> * * 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 @@ -26,53 +26,145 @@ #include <sys/resource.h> enum { - BENCHMARK_ZLIB, - BENCHMARK_FIB, - BENCHMARK_MD5, - BENCHMARK_SHA1, BENCHMARK_BLOWFISH, + BENCHMARK_CRYPTOHASH, + BENCHMARK_FIB, + BENCHMARK_NQUEENS, + BENCHMARK_FFT, BENCHMARK_RAYTRACE, BENCHMARK_N_ENTRIES } Entries; -void scan_zlib(gboolean reload); +void scan_fft(gboolean reload); void scan_raytr(gboolean reload); void scan_bfsh(gboolean reload); -void scan_md5(gboolean reload); +void scan_cryptohash(gboolean reload); void scan_fib(gboolean reload); -void scan_sha1(gboolean reload); +void scan_nqueens(gboolean reload); -gchar *callback_zlib(); +gchar *callback_fft(); gchar *callback_raytr(); gchar *callback_bfsh(); -gchar *callback_md5(); gchar *callback_fib(); -gchar *callback_sha1(); +gchar *callback_cryptohash(); +gchar *callback_nqueens(); static ModuleEntry entries[] = { - {"CPU ZLib", "compress.png", callback_zlib, scan_zlib}, - {"CPU Fibonacci", "module.png", callback_fib, scan_fib}, - {"CPU MD5", "module.png", callback_md5, scan_md5}, - {"CPU SHA1", "module.png", callback_sha1, scan_sha1}, {"CPU Blowfish", "blowfish.png", callback_bfsh, scan_bfsh}, + {"CPU CryptoHash", "cryptohash.png", callback_cryptohash, scan_cryptohash}, + {"CPU Fibonacci", "nautilus.png", callback_fib, scan_fib}, + {"CPU N-Queens", "nqueens.png", callback_nqueens, scan_nqueens}, + {"FPU FFT", "fft.png", callback_fft, scan_fft}, {"FPU Raytracing", "raytrace.png", callback_raytr, scan_raytr}, {NULL} }; +typedef struct _ParallelBenchTask ParallelBenchTask; + +struct _ParallelBenchTask { + guint start, end; + gpointer data, callback; +}; + +gpointer benchmark_parallel_for_dispatcher(gpointer data) +{ + ParallelBenchTask *pbt = (ParallelBenchTask *)data; + gpointer (*callback)(unsigned int start, unsigned int end, void *data); + gpointer return_value; + + if ((callback = pbt->callback)) { + DEBUG("this is thread %p; items %d -> %d, data %p", g_thread_self(), + pbt->start, pbt->end, pbt->data); + return_value = callback(pbt->start, pbt->end, pbt->data); + DEBUG("this is thread %p; return value is %p", g_thread_self(), return_value); + } else { + DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self()); + } + + g_free(pbt); + + return return_value; +} + +gdouble benchmark_parallel_for(guint start, guint end, + gpointer callback, gpointer callback_data) { + gchar *temp; + guint n_cores, iter_per_core, iter; + gdouble elapsed_time; + GSList *threads = NULL, *t; + GTimer *timer; + + timer = g_timer_new(); + + temp = module_call_method("devices::getProcessorCount"); + n_cores = temp ? atoi(temp) : 1; + g_free(temp); + + while (1) { + iter_per_core = (end - start) / n_cores; + + if (iter_per_core == 0) { + DEBUG("not enough items per core; disabling one"); + n_cores--; + } else { + break; + } + } + + DEBUG("processor has %d cores; processing %d elements (%d per core)", + n_cores, (end - start), iter_per_core); + + g_timer_start(timer); + for (iter = start; iter < end; iter += iter_per_core) { + ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); + GThread *thread; + + DEBUG("launching thread %d", 1 + (iter / iter_per_core)); + + pbt->start = iter == 0 ? 0 : iter + 1; + pbt->end = iter + iter_per_core - 1; + pbt->data = callback_data; + pbt->callback = callback; + + if (pbt->end > end) + pbt->end = end; + + thread = g_thread_create((GThreadFunc) benchmark_parallel_for_dispatcher, + pbt, TRUE, NULL); + threads = g_slist_append(threads, thread); + + DEBUG("thread %d launched as context %p", 1 + (iter / iter_per_core), threads->data); + } + + DEBUG("waiting for all threads to finish"); + for (t = threads; t; t = t->next) { + DEBUG("waiting for thread with context %p", t->data); + g_thread_join((GThread *)t->data); + } + + g_timer_stop(timer); + elapsed_time = g_timer_elapsed(timer, NULL); + + g_slist_free(threads); + g_timer_destroy(timer); + + DEBUG("finishing; all threads took %f seconds to finish", elapsed_time); + + return elapsed_time; +} + static gchar *__benchmark_include_results(gdouble result, const gchar * benchmark, ShellOrderType order_type) { GKeyFile *conf; gchar **machines; - gchar *path, *results = g_strdup(""); + gchar *path, *results = g_strdup(""), *return_value, *processor_frequency; int i; conf = g_key_file_new(); - path = - g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf", - NULL); + path = g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf", NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { DEBUG("local benchmark.conf not found, trying system-wide"); g_free(path); @@ -95,17 +187,24 @@ static gchar *__benchmark_include_results(gdouble result, g_free(path); g_key_file_free(conf); - DEBUG("results = %s", results); - - return g_strdup_printf("[$ShellParam$]\n" - "Zebra=1\n" - "OrderType=%d\n" - "ViewType=3\n" - "[%s]\n" - "<i>This Machine</i>=%.3f\n" - "%s", order_type, benchmark, result, results); + processor_frequency = module_call_method("devices::getProcessorFrequency"); + return_value = g_strdup_printf("[$ShellParam$]\n" + "Zebra=1\n" + "OrderType=%d\n" + "ViewType=3\n" + "ColumnTitle$Extra1=CPU Clock\n" + "ColumnTitle$Progress=Results\n" + "ColumnTitle$TextValue=CPU\n" + "ShowColumnHeaders=true\n" + "[%s]\n" + "<big><b>This Machine</b></big>=%.3f|%s MHz\n" + "%s", order_type, benchmark, result, processor_frequency, results); + g_free(processor_frequency); + return return_value; } + + static gchar *benchmark_include_results_reverse(gdouble result, const gchar * benchmark) { @@ -123,16 +222,22 @@ static gchar *benchmark_include_results(gdouble result, static gdouble bench_results[BENCHMARK_N_ENTRIES]; #include <arch/common/fib.h> -#include <arch/common/zlib.h> -#include <arch/common/md5.h> -#include <arch/common/sha1.h> +#include <arch/common/cryptohash.h> #include <arch/common/blowfish.h> #include <arch/common/raytrace.h> +#include <arch/common/nqueens.h> +#include <arch/common/fft.h> + +gchar *callback_fft() +{ + return benchmark_include_results(bench_results[BENCHMARK_FFT], + "FPU FFT"); +} -gchar *callback_zlib() +gchar *callback_nqueens() { - return benchmark_include_results_reverse(bench_results[BENCHMARK_ZLIB], - "CPU ZLib"); + return benchmark_include_results_reverse(bench_results[BENCHMARK_NQUEENS], + "CPU N-Queens"); } gchar *callback_raytr() @@ -147,10 +252,10 @@ gchar *callback_bfsh() "CPU Blowfish"); } -gchar *callback_md5() +gchar *callback_cryptohash() { - return benchmark_include_results_reverse(bench_results[BENCHMARK_MD5], - "CPU MD5"); + return benchmark_include_results_reverse(bench_results[BENCHMARK_CRYPTOHASH], + "CPU Cryptohash"); } gchar *callback_fib() @@ -159,12 +264,6 @@ gchar *callback_fib() "CPU Fibonacci"); } -gchar *callback_sha1() -{ - return benchmark_include_results_reverse(bench_results[BENCHMARK_SHA1], - "CPU SHA1"); -} - #define RUN_WITH_HIGH_PRIORITY(fn) \ do { \ int old_priority = getpriority(PRIO_PROCESS, 0); \ @@ -173,10 +272,17 @@ gchar *callback_sha1() setpriority(PRIO_PROCESS, 0, old_priority); \ } while (0); -void scan_zlib(gboolean reload) +void scan_fft(gboolean reload) +{ + SCAN_START(); + RUN_WITH_HIGH_PRIORITY(benchmark_fft); + SCAN_END(); +} + +void scan_nqueens(gboolean reload) { SCAN_START(); - RUN_WITH_HIGH_PRIORITY(benchmark_zlib); + RUN_WITH_HIGH_PRIORITY(benchmark_nqueens); SCAN_END(); } @@ -194,10 +300,10 @@ void scan_bfsh(gboolean reload) SCAN_END(); } -void scan_md5(gboolean reload) +void scan_cryptohash(gboolean reload) { SCAN_START(); - RUN_WITH_HIGH_PRIORITY(benchmark_md5); + RUN_WITH_HIGH_PRIORITY(benchmark_cryptohash); SCAN_END(); } @@ -208,26 +314,16 @@ void scan_fib(gboolean reload) SCAN_END(); } -void scan_sha1(gboolean reload) -{ - SCAN_START(); - RUN_WITH_HIGH_PRIORITY(benchmark_sha1); - SCAN_END(); -} - const gchar *hi_note_func(gint entry) { switch (entry) { - case BENCHMARK_ZLIB: - return "Results in KiB/second. Higher is better."; - - case BENCHMARK_MD5: - case BENCHMARK_SHA1: + case BENCHMARK_CRYPTOHASH: return "Results in MiB/second. Higher is better."; case BENCHMARK_RAYTRACE: case BENCHMARK_BLOWFISH: case BENCHMARK_FIB: + case BENCHMARK_NQUEENS: return "Results in seconds. Lower is better."; } @@ -268,26 +364,31 @@ static gchar *get_benchmark_results() gint i = G_N_ELEMENTS(entries) - 1; gchar *machine = module_call_method("devices::getProcessorName"); - gchar *param = g_strdup_printf("[param]\n" - "machine=%s\n" "nbenchmarks=%d\n", - machine, i); - gchar *result = param; - + gchar *machineclock = module_call_method("devices::getProcessorFrequency"); + gchar *machineram = module_call_method("devices::getMemoryTotal"); + gchar *result = g_strdup_printf("[param]\n" + "machine=%s\n" + "machineclock=%s\n" + "machineram=%s\n" + "nbenchmarks=%d\n", + machine, + machineclock, + machineram, i); for (; i >= 0; i--) { if ((scan_callback = entries[i].scan_callback)) { scan_callback(FALSE); - result = g_strdup_printf("%s\n" - "[bench%d]\n" - "name=%s\n" - "value=%f\n", - result, - i, entries[i].name, bench_results[i]); + result = h_strdup_cprintf("[bench%d]\n" + "name=%s\n" + "value=%f\n", + result, + i, entries[i].name, bench_results[i]); } } g_free(machine); - g_free(param); + g_free(machineclock); + g_free(machineram); return result; } @@ -310,3 +411,10 @@ void hi_module_init(void) sync_manager_add_entry(&se[0]); sync_manager_add_entry(&se[1]); } + +gchar **hi_module_get_dependencies(void) +{ + static gchar *deps[] = { "devices.so", NULL }; + + return deps; +} |