* Add generic parser for bench. * Factorization

This commit is contained in:
Patrick Pelissier committed 2019-12-07 11:58:19 +01:00
1 parent 90f248fbe8
commit 65765763ae
2 files changed
+163 -27

No files matched your search

+97
View File
@@ -23,6 +23,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "common.h"
void compiler_barrier(void *p)
@@ -32,3 +33,99 @@ void compiler_barrier(void *p)
// Can be used for FLTO building
// asm volatile("": "+r" (p) : :"memory");
}
struct parse_opt_s {
int test_function;
double from, to, step, grow;
bool graph;
};
static void
parse_config(struct parse_opt_s *opt, int argc, const char *argv[])
{
char *end;
opt->test_function = 0;
opt->from = 0.0;
opt->to = 0.0;
opt->step = 0.0;
opt->grow = 1.1;
opt->graph = false;
for(int i = 1; i < argc ; i++)
{
if (argv[i][0] == '-') {
if (strcmp(argv[i], "--from") == 0){
i++;
opt->from = strtod(argv[i], &end);
opt->to = opt->from;
} else if (strcmp(argv[i], "--to") == 0) {
i++;
opt->to = strtod(argv[i], &end);
opt->grow = 1.1;
} else if (strcmp(argv[i], "--step") == 0) {
i++;
opt->step = strtod(argv[i], &end);
opt->grow = 0;
} else if (strcmp(argv[i], "--grow") == 0) {
i++;
opt->grow = strtod(argv[i], &end);
opt->step = 0;
} else if (strcmp(argv[i], "--graph") == 0) {
opt->graph = true;
} else {
fprintf(stderr, "ERROR: Option unkown: %s.\n",
argv[i]);
exit(-1);
}
if (*end != 0) {
fprintf(stderr, "ERROR: Cannot parse %s. Expected float\n",
argv[i]);
exit(-1);
}
} else {
opt->test_function = strtol (argv[i], &end, 10);
if (*end != 0) {
fprintf(stderr, "ERROR: Cannot parse %s. Expected integer\n",
argv[i]);
exit(-1);
}
}
}
}
static int
select_config(int func, size_t n, const config_func_t functions[])
{
for(size_t i = 0; i < n;i++) {
if (functions[i].num == func)
return i;
}
fprintf(stderr, "ERROR: Function number %d not found\n", func);
exit(-1);
}
void
test(size_t n, const config_func_t functions[], int argc, const char *argv[])
{
// options
// NUMBER
// --from NUMBER --to NUMBER --step NUMBER --grow NUMBER
// --graph
struct parse_opt_s arg;
parse_config(&arg, argc, argv);
int i = select_config(arg.test_function, n, functions);
double from = arg.from == 0 ? functions[i].default_n : arg.from;
double to = arg.from == 0 ? functions[i].default_n : arg.to;
// Do the bench
for(double n = from; n <= to ; n = (arg.grow == 0 ? n + arg.step : n * arg.grow))
{
if (functions[i].init != NULL)
functions[i].init(n);
test_function(functions[i].funcname, (size_t) n, functions[i].func);
if (functions[i].clear != NULL)
functions[i].clear();
}
return;
}
+66 -27
View File
@@ -27,36 +27,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Needed for M_THREAD_ATTR
#if defined(MULTI_THREAD_MEASURE)
#include "m-mutex.h"
#endif
#if defined(_WIN32)
/* WINDOWS variant */
#include <windows.h>
# include <windows.h>
#elif (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/types.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# define USE_SYSCTL
#else
# include <sys/types.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <unistd.h>
#endif
// Number of elements of a table
#define numberof(x) (sizeof(x)/sizeof(x[0]))
/* Get the current CPU time. */
#if defined(_WIN32)
/* WINDOWS variant */
static inline unsigned long long
cputime (void)
{
LARGE_INTEGER freq, val;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&val);
return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart);
LARGE_INTEGER freq, val;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&val);
return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart);
}
#else
/* UNIX variant */
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/time.h>
static inline unsigned long long
cputime (void)
{
#if defined(MULTI_THREAD_MEASURE)
// Multi thread
// Multi thread: Uses real time
struct timeval tv;
gettimeofday (&tv, NULL);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
#else
// Single thread
// Single thread: Uses process usage time
struct rusage rus;
getrusage (0, &rus);
return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec;
@@ -65,46 +86,64 @@ cputime (void)
#endif
static unsigned long g_result;
// The result of the bench
#ifdef __cplusplus
static
#endif
unsigned long g_result;
// The rand value
static
#if defined(MULTI_THREAD_MEASURE)
M_THREAD_ATTR
#endif
unsigned int randValue = 0;
// Pseudo rand value generator.
// Not very random but sufficient and fast enough for the bench
static inline void rand_init(void)
{
randValue = 0;
}
static inline unsigned int rand_get(void)
{
randValue = randValue * 31421U + 6927U;
return randValue;
}
static inline void test_function(const char str[], size_t n, void (*func)(size_t))
// The function that performs the bench
static inline double
test_function(const char *str, size_t n, void (*func)(size_t))
{
double result;
unsigned long long start, end;
rand_init();
start = cputime();
(*func)(n);
end = cputime();
result = (double)(end-start) / 1000.0;
end = (end - start) / 1000U;
printf ("%s %lu ms for n = %lu [r=%lu]\n", str, (unsigned long) end, (unsigned long) n, g_result);
if (str != NULL) {
printf ("%20.20s time %lu ms for n = %lu [r=%lu]\n", str, (unsigned long) end, (unsigned long) n, g_result);
}
return result;
}
#if defined(_WIN32)
# include <windows.h>
#elif (defined(__APPLE__) && defined(__MACH__)) \
|| defined(__DragonFly__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/param.h>
# include <sys/sysctl.h>
# define USE_SYSCTL
#else
# include <unistd.h>
// Configuration table
typedef struct {
int num;
const char *funcname;
size_t default_n;
void (*init)(size_t);
void (*func)(size_t);
void (*clear)(void);
} config_func_t;
// Perform a parsing of the given arguments and do the bench according to the table
#ifdef __cplusplus
extern "C"
#endif
void test(size_t n, const config_func_t functions[], int argc, const char *argv[]);
/* Return the number of CPU of the system */
static inline int get_cpu_count(void)