1*5f32b710SXin Li #include <benchmark/benchmark.h>
2*5f32b710SXin Li
3*5f32b710SXin Li #include <fp16.h>
4*5f32b710SXin Li #ifndef EMSCRIPTEN
5*5f32b710SXin Li #include <fp16/psimd.h>
6*5f32b710SXin Li #endif
7*5f32b710SXin Li
next_xorshift16(uint16_t x)8*5f32b710SXin Li static inline uint16_t next_xorshift16(uint16_t x) {
9*5f32b710SXin Li x ^= x >> 8;
10*5f32b710SXin Li x ^= x << 9;
11*5f32b710SXin Li x ^= x >> 5;
12*5f32b710SXin Li return x;
13*5f32b710SXin Li }
14*5f32b710SXin Li
next_xorshift32(uint32_t x)15*5f32b710SXin Li static inline uint32_t next_xorshift32(uint32_t x) {
16*5f32b710SXin Li x ^= x >> 13;
17*5f32b710SXin Li x ^= x << 17;
18*5f32b710SXin Li x ^= x >> 5;
19*5f32b710SXin Li return x;
20*5f32b710SXin Li }
21*5f32b710SXin Li #ifndef EMSCRIPTEN
next_xorshift16_psimd(psimd_u16 x)22*5f32b710SXin Li PSIMD_INTRINSIC psimd_u16 next_xorshift16_psimd(psimd_u16 x) {
23*5f32b710SXin Li x ^= x >> psimd_splat_u16(8);
24*5f32b710SXin Li x ^= x << psimd_splat_u16(9);
25*5f32b710SXin Li x ^= x >> psimd_splat_u16(5);
26*5f32b710SXin Li return x;
27*5f32b710SXin Li }
28*5f32b710SXin Li #endif
29*5f32b710SXin Li
30*5f32b710SXin Li
fp16_alt_to_fp32_bits(benchmark::State & state)31*5f32b710SXin Li static void fp16_alt_to_fp32_bits(benchmark::State& state) {
32*5f32b710SXin Li uint16_t fp16 = UINT16_C(0x7C00);
33*5f32b710SXin Li while (state.KeepRunning()) {
34*5f32b710SXin Li const uint32_t fp32 = fp16_alt_to_fp32_bits(fp16);
35*5f32b710SXin Li
36*5f32b710SXin Li fp16 = next_xorshift16(fp16);
37*5f32b710SXin Li benchmark::DoNotOptimize(fp32);
38*5f32b710SXin Li }
39*5f32b710SXin Li }
40*5f32b710SXin Li BENCHMARK(fp16_alt_to_fp32_bits);
41*5f32b710SXin Li
fp16_alt_to_fp32_value(benchmark::State & state)42*5f32b710SXin Li static void fp16_alt_to_fp32_value(benchmark::State& state) {
43*5f32b710SXin Li uint16_t fp16 = UINT16_C(0x7C00);
44*5f32b710SXin Li while (state.KeepRunning()) {
45*5f32b710SXin Li const float fp32 = fp16_alt_to_fp32_value(fp16);
46*5f32b710SXin Li
47*5f32b710SXin Li fp16 = next_xorshift16(fp16);
48*5f32b710SXin Li benchmark::DoNotOptimize(fp32);
49*5f32b710SXin Li }
50*5f32b710SXin Li }
51*5f32b710SXin Li BENCHMARK(fp16_alt_to_fp32_value);
52*5f32b710SXin Li
53*5f32b710SXin Li #ifndef EMSCRIPTEN
fp16_alt_to_fp32_psimd(benchmark::State & state)54*5f32b710SXin Li static void fp16_alt_to_fp32_psimd(benchmark::State& state) {
55*5f32b710SXin Li psimd_u16 fp16 = (psimd_u16) { 0x7C00, 0x7C01, 0x7C02, 0x7C03 };
56*5f32b710SXin Li while (state.KeepRunning()) {
57*5f32b710SXin Li const psimd_f32 fp32 = fp16_alt_to_fp32_psimd(fp16);
58*5f32b710SXin Li
59*5f32b710SXin Li fp16 = next_xorshift16_psimd(fp16);
60*5f32b710SXin Li benchmark::DoNotOptimize(fp32);
61*5f32b710SXin Li }
62*5f32b710SXin Li }
63*5f32b710SXin Li BENCHMARK(fp16_alt_to_fp32_psimd);
64*5f32b710SXin Li
fp16_alt_to_fp32x2_psimd(benchmark::State & state)65*5f32b710SXin Li static void fp16_alt_to_fp32x2_psimd(benchmark::State& state) {
66*5f32b710SXin Li psimd_u16 fp16 =
67*5f32b710SXin Li (psimd_u16) { 0x7C00, 0x7C01, 0x7C02, 0x7C03, 0x7C04, 0x7C05, 0x7C06, 0x7C07 };
68*5f32b710SXin Li while (state.KeepRunning()) {
69*5f32b710SXin Li const psimd_f32x2 fp32 = fp16_alt_to_fp32x2_psimd(fp16);
70*5f32b710SXin Li
71*5f32b710SXin Li fp16 = next_xorshift16_psimd(fp16);
72*5f32b710SXin Li benchmark::DoNotOptimize(fp32);
73*5f32b710SXin Li }
74*5f32b710SXin Li }
75*5f32b710SXin Li BENCHMARK(fp16_alt_to_fp32x2_psimd);
76*5f32b710SXin Li #endif
77*5f32b710SXin Li
fp16_alt_from_fp32_value(benchmark::State & state)78*5f32b710SXin Li static void fp16_alt_from_fp32_value(benchmark::State& state) {
79*5f32b710SXin Li uint32_t fp32 = UINT32_C(0x7F800000);
80*5f32b710SXin Li while (state.KeepRunning()) {
81*5f32b710SXin Li const uint16_t fp16 = fp16_alt_from_fp32_value(fp32_from_bits(fp32));
82*5f32b710SXin Li
83*5f32b710SXin Li fp32 = next_xorshift32(fp32);
84*5f32b710SXin Li benchmark::DoNotOptimize(fp16);
85*5f32b710SXin Li }
86*5f32b710SXin Li }
87*5f32b710SXin Li BENCHMARK(fp16_alt_from_fp32_value);
88*5f32b710SXin Li
89*5f32b710SXin Li BENCHMARK_MAIN();
90