* Add generic parser for bench. * Factorization
This commit is contained in:
1 parent
90f248fbe8
commit
65765763ae
2 files changed
+163
-27
No files matched your search
@@ -23,6 +23,7 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
void compiler_barrier(void *p)
|
void compiler_barrier(void *p)
|
||||||
@@ -32,3 +33,99 @@ void compiler_barrier(void *p)
|
|||||||
// Can be used for FLTO building
|
// Can be used for FLTO building
|
||||||
// asm volatile("": "+r" (p) : :"memory");
|
// 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
@@ -27,36 +27,57 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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)
|
#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
|
static inline unsigned long long
|
||||||
cputime (void)
|
cputime (void)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER freq, val;
|
LARGE_INTEGER freq, val;
|
||||||
QueryPerformanceFrequency(&freq);
|
QueryPerformanceFrequency(&freq);
|
||||||
QueryPerformanceCounter(&val);
|
QueryPerformanceCounter(&val);
|
||||||
return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart);
|
return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* UNIX variant */
|
/* UNIX variant */
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
static inline unsigned long long
|
static inline unsigned long long
|
||||||
cputime (void)
|
cputime (void)
|
||||||
{
|
{
|
||||||
#if defined(MULTI_THREAD_MEASURE)
|
#if defined(MULTI_THREAD_MEASURE)
|
||||||
// Multi thread
|
// Multi thread: Uses real time
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
gettimeofday (&tv, NULL);
|
gettimeofday (&tv, NULL);
|
||||||
return tv.tv_sec * 1000000ULL + tv.tv_usec;
|
return tv.tv_sec * 1000000ULL + tv.tv_usec;
|
||||||
#else
|
#else
|
||||||
// Single thread
|
// Single thread: Uses process usage time
|
||||||
struct rusage rus;
|
struct rusage rus;
|
||||||
getrusage (0, &rus);
|
getrusage (0, &rus);
|
||||||
return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec;
|
return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec;
|
||||||
@@ -65,46 +86,64 @@ cputime (void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static unsigned long g_result;
|
// The result of the bench
|
||||||
|
#ifdef __cplusplus
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
unsigned long g_result;
|
||||||
|
|
||||||
|
// The rand value
|
||||||
static
|
static
|
||||||
#if defined(MULTI_THREAD_MEASURE)
|
#if defined(MULTI_THREAD_MEASURE)
|
||||||
M_THREAD_ATTR
|
M_THREAD_ATTR
|
||||||
#endif
|
#endif
|
||||||
unsigned int randValue = 0;
|
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)
|
static inline void rand_init(void)
|
||||||
{
|
{
|
||||||
randValue = 0;
|
randValue = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int rand_get(void)
|
static inline unsigned int rand_get(void)
|
||||||
{
|
{
|
||||||
randValue = randValue * 31421U + 6927U;
|
randValue = randValue * 31421U + 6927U;
|
||||||
return randValue;
|
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;
|
unsigned long long start, end;
|
||||||
rand_init();
|
rand_init();
|
||||||
start = cputime();
|
start = cputime();
|
||||||
(*func)(n);
|
(*func)(n);
|
||||||
end = cputime();
|
end = cputime();
|
||||||
|
result = (double)(end-start) / 1000.0;
|
||||||
end = (end - start) / 1000U;
|
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)
|
// Configuration table
|
||||||
# include <windows.h>
|
typedef struct {
|
||||||
#elif (defined(__APPLE__) && defined(__MACH__)) \
|
int num;
|
||||||
|| defined(__DragonFly__) || defined(__FreeBSD__) \
|
const char *funcname;
|
||||||
|| defined(__NetBSD__) || defined(__OpenBSD__)
|
size_t default_n;
|
||||||
# include <sys/param.h>
|
void (*init)(size_t);
|
||||||
# include <sys/sysctl.h>
|
void (*func)(size_t);
|
||||||
# define USE_SYSCTL
|
void (*clear)(void);
|
||||||
#else
|
} config_func_t;
|
||||||
# include <unistd.h>
|
|
||||||
|
// Perform a parsing of the given arguments and do the bench according to the table
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
void test(size_t n, const config_func_t functions[], int argc, const char *argv[]);
|
||||||
|
|
||||||
/* Return the number of CPU of the system */
|
/* Return the number of CPU of the system */
|
||||||
static inline int get_cpu_count(void)
|
static inline int get_cpu_count(void)
|
||||||
|
|||||||
Reference in new issue
Block a user