summaryrefslogtreecommitdiff
path: root/src/tc-time.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tc-time.c')
-rw-r--r--src/tc-time.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/src/tc-time.c b/src/tc-time.c
index e842e77..e86ed67 100644
--- a/src/tc-time.c
+++ b/src/tc-time.c
@@ -5,6 +5,7 @@
* modify it under the terms of the WTF Public License version 2 or
* (at your option) any later version.
*/
+#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,10 +37,12 @@ static const struct timespec pairs[] = {
};
/*
- * Variant that uses full 64 bit division and is thus slower on
- * a handful of hardware.
+ * The playing fields it not level at all!
+ * HX_timespec_add_DIVQ benefits from inlining and near jumps,
+ * while HX_timespec_add has to go via PLT, and also has the PIC tax.
+ * It is actually worse by 7% on i7-8250U/-m64.
*/
-static struct timespec *HX_timespec_add_FDIV(struct timespec *r,
+static struct timespec *HX_timespec_add_DIVQ(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
long long p, q;
@@ -105,6 +108,20 @@ HX_timespec_mulf_S(struct timespec *r, const struct timespec *a, double f)
return r;
}
+static void test_basic(void)
+{
+ struct timeval a = {1, 769298}, b = {2, 430520}, c;
+ struct timespec p = {1, 769298000}, q = {2, 430520000}, r;
+ HX_timeval_sub(&c, &b, &a);
+ HX_timespec_sub(&r, &q, &p);
+ printf(HX_TIMEVAL_FMT "\n", HX_TIMEVAL_EXP(&c));
+ printf(HX_TIMESPEC_FMT "\n", HX_TIMESPEC_EXP(&r));
+ assert(c.tv_sec == 0);
+ assert(c.tv_usec == 661222);
+ assert(r.tv_sec == 0);
+ assert(r.tv_nsec == 661222000);
+}
+
static void test_same(void)
{
static const struct timespec zero = {0, 0};
@@ -205,9 +222,9 @@ static void test_add(void)
for (a = pairs; a < pairs + ARRAY_SIZE(pairs); ++a) {
for (b = pairs; b < pairs + ARRAY_SIZE(pairs); ++b) {
HX_timespec_add(&r, a, b);
- print_op2(&r, a, "+N", b);
- HX_timespec_add_FDIV(&s, a, b);
- print_op2(&r, a, "+F", b);
+ print_op2(&r, a, "+L", b);
+ HX_timespec_add_DIVQ(&s, a, b);
+ print_op2(&r, a, "+Q", b);
if (r.tv_sec != s.tv_sec || r.tv_nsec != s.tv_nsec)
abort();
HX_timespec_sub(&r, a, b);
@@ -288,7 +305,7 @@ static void test_adds(void)
{
printf("# Test addition speed\n");
test_adds_1("normal: ", HX_timespec_add);
- test_adds_1("fulldiv: ", HX_timespec_add_FDIV);
+ test_adds_1("div64: ", HX_timespec_add_DIVQ);
printf("\n");
}
@@ -335,11 +352,10 @@ static void test_mul(void)
static void test_muls_1i(const char *text, mul_func_t fn)
{
struct timespec r, s, start, delta;
- unsigned int i;
printf("%s", text);
clock_gettime(clock_id, &start);
- for (i = 0; i < step_mul; ++i) {
+ for (time_t i = 0; i < step_mul; ++i) {
r.tv_sec = -i;
r.tv_nsec = -i / 4;
(*fn)(&s, &r, 7);
@@ -352,11 +368,10 @@ static void test_muls_1i(const char *text, mul_func_t fn)
static void test_muls_1f(const char *text, mulf_func_t fn)
{
struct timespec r, s, start, delta;
- unsigned int i;
printf("%s", text);
clock_gettime(clock_id, &start);
- for (i = 0; i < step_mul; ++i) {
+ for (time_t i = 0; i < step_mul; ++i) {
r.tv_sec = -i;
r.tv_nsec = -i / 4;
(*fn)(&s, &r, 7);
@@ -382,6 +397,7 @@ int main(void)
if (HX_init() <= 0)
abort();
+ test_basic();
test_same();
test_neg();
test_add();