/* * M*LIB - common functions for bench module * * Copyright (c) 2017-2018, Patrick Pelissier * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * + Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * + Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __COMMON_BENCH__H #define __COMMON_BENCH__H #if defined(_WIN32) /* WINDOWS variant */ #include static unsigned long long cputime (void) { LARGE_INTEGER freq, val; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&val); return (unsigned long long) (1000000. * (double) val.QuadPart / (double) freq.QuadPart); } #else /* UNIX variant */ #include #include #include static unsigned long long cputime (void) { #if defined(MULTI_THREAD_MEASURE) // Multi thread struct timeval tv; gettimeofday (&tv, NULL); return tv.tv_sec * 1000000ULL + tv.tv_usec; #else // Single thread struct rusage rus; getrusage (0, &rus); return rus.ru_utime.tv_sec * 1000000ULL + rus.ru_utime.tv_usec; #endif } #endif unsigned long g_result; unsigned int randValue = 0; static void rand_init(void) { randValue = 0; } static unsigned int rand_get(void) { randValue = randValue * 31421U + 6927U; return randValue; } static void test_function(const char str[], size_t n, void (*func)(size_t)) { unsigned long long start, end; rand_init(); start = cputime(); (*func)(n); end = cputime(); end = (end - start) / 1000U; printf ("%s %lu ms for n = %lu [r=%lu]\n", str, (unsigned long) end, (unsigned long) n, g_result); } #if defined(_WIN32) # include #elif (defined(__APPLE__) && defined(__MACH__)) \ || defined(__DragonFly__) || defined(__FreeBSD__) \ || defined(__NetBSD__) || defined(__OpenBSD__) # include # include # define USE_SYSCTL #else # include #endif /* Return the number of CPU of the system */ static inline int get_cpu_count(void) { #if defined(_WIN32) SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; #elif defined(USE_SYSCTL) int nm[2]; int count = 0; size_t len = sizeof (count); nm[0] = CTL_HW; nm[1] = HW_NCPU; sysctl(nm, 2, &count, &len, NULL, 0); return MAX(1, count); #elif defined (_SC_NPROCESSORS_ONLN) return sysconf(_SC_NPROCESSORS_ONLN); #else return 1; #endif } #endif