diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/benchmark.c | 102 | 
1 files changed, 101 insertions, 1 deletions
| diff --git a/modules/benchmark.c b/modules/benchmark.c index ed23243b..62720530 100644 --- a/modules/benchmark.c +++ b/modules/benchmark.c @@ -91,8 +91,94 @@ struct _ParallelBenchTask {      gint	thread_number;      guint	start, end;      gpointer	data, callback; +    int *stop;  }; +static gpointer benchmark_crunch_for_dispatcher(gpointer data) +{ +    ParallelBenchTask 	*pbt = (ParallelBenchTask *)data; +    gpointer (*callback)(void *data, gint thread_number); +    gpointer return_value = g_malloc(sizeof(int)); +    int count = 0; + +    if ((callback = pbt->callback)) { +        while(!*pbt->stop) { +            callback(pbt->data, pbt->thread_number); +            /* don't count if didn't finish in time */ +            if (!*pbt->stop) +                count++; +        } +    } else { +        DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self()); +    } + +    g_free(pbt); + +    *(double*)return_value = (double)count; +    return return_value; +} + +bench_value benchmark_crunch_for(float seconds, gint n_threads, +                               gpointer callback, gpointer callback_data) { +    int cpu_procs, cpu_cores, cpu_threads, thread_number, stop = 0; +    GSList *threads = NULL, *t; +    GTimer *timer; +    bench_value ret = EMPTY_BENCH_VALUE; + +    timer = g_timer_new(); + +    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); +    if (n_threads > 0) +        ret.threads_used = n_threads; +    else if (n_threads < 0) +        ret.threads_used = cpu_cores; +    else +        ret.threads_used = cpu_threads; + +    g_timer_start(timer); +    for (thread_number = 0; thread_number < ret.threads_used; thread_number++) { +        ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); +        GThread *thread; + +        DEBUG("launching thread %d", thread_number); + +        pbt->thread_number = thread_number; +        pbt->data     = callback_data; +        pbt->callback = callback; +        pbt->stop = &stop; + +        thread = g_thread_new("dispatcher", +            (GThreadFunc)benchmark_crunch_for_dispatcher, pbt); +        threads = g_slist_prepend(threads, thread); + +        DEBUG("thread %d launched as context %p", thread_number, thread); +    } + +    /* wait for time */ +    //while ( g_timer_elapsed(timer, NULL) < seconds ) { } +    g_usleep(seconds * 1000000); + +    /* signal all threads to stop */ +    stop = 1; +    g_timer_stop(timer); + +    ret.result = 0; +    DEBUG("waiting for all threads to finish"); +    for (t = threads; t; t = t->next) { +        DEBUG("waiting for thread with context %p", t->data); +        gpointer *rv = g_thread_join((GThread *)t->data); +        ret.result += *(double*)rv; +        g_free(rv); +    } + +    ret.elapsed_time = g_timer_elapsed(timer, NULL); + +    g_slist_free(threads); +    g_timer_destroy(timer); + +    return ret; +} +  static gpointer benchmark_parallel_for_dispatcher(gpointer data)  {      ParallelBenchTask 	*pbt = (ParallelBenchTask *)data; @@ -113,6 +199,15 @@ static gpointer benchmark_parallel_for_dispatcher(gpointer data)      return return_value;  } +/* one call for each thread to be used */ +bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data) { +    int cpu_procs, cpu_cores, cpu_threads; +    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); +    if (n_threads == 0) n_threads = cpu_threads; +    else if (n_threads == -1) n_threads = cpu_cores; +    return  benchmark_parallel_for(n_threads, 0, n_threads, callback, callback_data); +} +  bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,                                 gpointer callback, gpointer callback_data) {      gchar	*temp; @@ -174,7 +269,12 @@ bench_value benchmark_parallel_for(gint n_threads, guint start, guint end,      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); +        gpointer *rv = g_thread_join((GThread *)t->data); +        if (rv) { +            if (ret.result == -1.0) ret.result = 0; +            ret.result += *(double*)rv; +        } +        g_free(rv);      }      g_timer_stop(timer); | 
