4#if FL_PLATFORM_HAS_LARGE_MEMORY
17float ulp_of(
float v) {
22double ulp_of(
double v) {
27typedef float (*ExpFn)(float);
29fl::u32 time_us(ExpFn fn,
const float* in, fl::u32 iterations,
float* sink) {
31 const fl::u32 t0 =
micros();
32 for (fl::u32 i = 0; i < iterations; ++i) {
33 acc += fn(in[i & 255u]);
35 const fl::u32 t1 =
micros();
40float call_fl_expf(
float x) {
return fl::expf(
x); }
41float call_libm_expf(
float x) { return ::expf(
x); }
42float call_fl_exp(
float x) {
return static_cast<float>(
fl::exp(
static_cast<double>(
x))); }
43float call_libm_exp(
float x) {
return static_cast<float>(::exp(
static_cast<double>(
x))); }
55 for (
float x = -103.9f;
x < 88.7f;
x += 0.05f) {
56 const float want = ::expf(
x);
58 if (want <= 0.0f || want != want || want > 3.0e38f) {
61 const float d = (got > want ? got - want : want - got) / ulp_of(want);
62 if (d > r.worst_ulp_float) {
63 r.worst_ulp_float = d;
68 for (
double x = -745.0;
x < 709.7;
x += 0.5) {
69 const double want = ::exp(
x);
71 if (want <= 0.0 || want != want) {
74 const double d = (got > want ? got - want : want - got) / ulp_of(want);
75 if (d > r.worst_ulp_double) {
76 r.worst_ulp_double = d;
81 r.accuracy_points = points;
84 static float inputs[256];
85 for (
int i = 0; i < 256; ++i) {
86 inputs[i] = -10.0f + 20.0f *
static_cast<float>(i) / 255.0f;
89 r.fl_expf_us = time_us(&call_fl_expf, inputs, iterations, &sink);
90 r.libm_expf_us = time_us(&call_libm_expf, inputs, iterations, &sink);
91 r.fl_exp_us = time_us(&call_fl_exp, inputs, iterations, &sink);
92 r.libm_exp_us = time_us(&call_libm_exp, inputs, iterations, &sink);
95 r.success = r.worst_ulp_float <= 2.0f && r.worst_ulp_double <= 2.0 && points > 0;
On-device accuracy and speed of fl::exp against the toolchain libm (#4288).
Result run(fl::u32 iterations)
Runs the accuracy sweep and the timed loops. iterations = calls per loop.
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
To bit_cast(const From &from) FL_NO_EXCEPT
enable_if< is_fixed_point< T >::value, T >::type exp(T x) FL_NO_EXCEPT
float expf(float value) FL_NO_EXCEPT
#define FL_PLATFORM_HAS_LARGE_MEMORY