Skip to content

Commit

Permalink
add single/veclibm.c
Browse files Browse the repository at this point in the history
  • Loading branch information
camel-cdr committed Oct 27, 2024
1 parent 507739a commit 260b1f7
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "thirdparty/veclibm"]
path = thirdparty/veclibm
url = https://github.com/rivosinc/veclibm
4 changes: 1 addition & 3 deletions bench/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
# define BENCH_VOLATILE(x) ({__asm volatile("" : "+g"(x) : "g"(x) : "memory");})
# define BENCH_VOLATILE_REG(x) ({__asm volatile("" : "+r"(x) : "r"(x) : "memory");})
# define BENCH_VOLATILE_MEM(x) ({__asm volatile("" : "+m"(x) : "m"(x) : "memory");})
# define BENCH_FENCE() ({__asm volatile("fence.i");})


#define BENCH_MAY_ALIAS __attribute__((__may_alias__))

Expand Down Expand Up @@ -164,7 +162,7 @@ bench_run(Bench *benches, size_t nBenches)

#define TIME \
for (ux beg = rv_cycles(), _once = 1; _once; \
BENCH_FENCE(), \
rv_fencei(), \
_cycles += rv_cycles() - beg, _once = 0)

#define BENCH_BEG(name) \
Expand Down
2 changes: 2 additions & 0 deletions nolibc.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ qsort(void *base, size_t len, size_t size, int (*cmp)(const void *, const void *
}
#endif

static void
rv_fencei() { __asm volatile("fence.i"); }

static ux
usqrt(ux y)
Expand Down
14 changes: 14 additions & 0 deletions single/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.POSIX:

include ../config.mk

EXECS=veclibm

all: ${EXECS}

veclibm: veclibm.c
${CC} ${CFLAGS} -o $@ $< ../thirdparty/veclibm/src/*.c -I ../thirdparty/veclibm/include -lm -Wno-unused -Wno-maybe-uninitialized

clean:
rm -f ${EXECS}

98 changes: 98 additions & 0 deletions single/veclibm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include <riscv_vector.h>

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef N
#define N (1024*128) /* change me */
#endif

static void
rvvlm_sqrt(size_t x_len, const double *x, double *y)
{
for (size_t vl; x_len > 0; x_len -= vl, x += vl, y += vl) {
vl = __riscv_vsetvl_e64m8(x_len);
vfloat64m8_t v = __riscv_vle64_v_f64m8(x, vl);
__riscv_vse64(y, __riscv_vfsqrt(v, vl), vl);
}
}

#define APPLY(X) \
X(exp) X(exp2) X(expm1) X(log) X(log10) X(log2) X(log1p) \
X(sqrt) X(cbrt) \
X(sin) X(cos) X(tan) X(asin) X(acos) X(atan) \
X(sinh) X(cosh) X(tanh) X(asinh) X(acosh) X(atanh) \
X(erf) X(erfc) X(tgamma) X(lgamma)

#define DECLARE(f) void rvvlm_##f(size_t x_len, const double *x, double *y);
APPLY(DECLARE)

#define DEFINE(f) \
static void lm_##f(size_t x_len, const double *x, double *y) { \
for (size_t i = 0; i < x_len; ++i) y[i] = f(x[i]); \
}
APPLY(DEFINE)
struct Func {
void (*rvvlm)(size_t, const double*, double*);
void (*lm)(size_t, const double*, double*);
const char *name;
};

struct Func funcs[] = {
#define ENTRY(f) { rvvlm_##f, lm_##f, #f },
APPLY(ENTRY)
};

typedef struct { uint64_t x, y, z; } URand;

/* RomuDuoJr, see https://romu-random.org/ */
static inline uint64_t
urand(URand *r)
{
#define ROTL(x,n) (((x) << (n)) | ((x) >> (8*sizeof(x) - (n))))
uint64_t xp = r->x, yp = r->y, zp = r->z;
r->x = 15241094284759029579u * zp;
r->y = ROTL(yp - xp, 12);
r->z = ROTL(zp - yp, 44);
return xp;
}


int
main(void)
{
double *in = malloc(N*sizeof *in), *out = malloc(N*sizeof *out);
URand r = {123, (uintptr_t)&in, (uintptr_t)&out};

for (size_t i = 0; i < N; ++i)
in[i] = (urand(&r) >> (64 - 53)) * (1.0 / (1ull << 53));

for (size_t i = 0; i < sizeof funcs / sizeof *funcs; ++i) {
size_t beg, end;
struct Func f = funcs[i];
printf("%s libm: ", f.name);
for (size_t i = 0; i < 3; ++i) {
__asm volatile("fence.i");
__asm volatile ("csrr %0, cycle" : "=r"(beg));
f.lm(N, in, out);
__asm volatile("fence.i");
__asm volatile ("csrr %0, cycle" : "=r"(end));
printf(" %f", ((double)N) / (end-beg));
}
printf(" elements/cycle\n%s rvvlm:", f.name);
for (size_t i = 0; i < 3; ++i) {
__asm volatile("fence.i");
__asm volatile ("csrr %0, cycle" : "=r"(beg));
f.rvvlm(N, in, out);
__asm volatile("fence.i");
__asm volatile ("csrr %0, cycle" : "=r"(end));
printf(" %f", ((double)N) / (end-beg));
}
printf(" elements/cycle\n");
}
free(in);
free(out);
return 0;
}

1 change: 1 addition & 0 deletions thirdparty/veclibm
Submodule veclibm added at deba35

0 comments on commit 260b1f7

Please sign in to comment.