summaryrefslogtreecommitdiff
path: root/benchmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'benchmark.c')
-rw-r--r--benchmark.c250
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;
+}