Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 1 | // Copyright 2022 The SwiftShader Authors. All Rights Reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Nicolas Capens | 93af45d | 2022-02-06 08:52:56 -0500 | [diff] [blame] | 15 | #include "ShaderCore.hpp" |
| 16 | #include "Reactor/Reactor.hpp" |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 17 | |
| 18 | #include "benchmark/benchmark.h" |
| 19 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 20 | #include <vector> |
| 21 | |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 22 | using namespace rr; |
| 23 | |
| 24 | BENCHMARK_MAIN(); |
| 25 | |
| 26 | // Macro that creates a lambda wrapper around the input overloaded function, |
| 27 | // creating a non-overload based on the args. This is useful for passing |
| 28 | // overloaded functions as template arguments. |
| 29 | // See https://stackoverflow.com/questions/25871381/c-overloaded-function-as-template-argument |
| 30 | #define LIFT(fname) \ |
| 31 | [](auto &&...args) -> decltype(auto) { \ |
| 32 | return fname(std::forward<decltype(args)>(args)...); \ |
| 33 | } |
| 34 | |
| 35 | template<typename Func, class... Args> |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 36 | static void Transcendental1(benchmark::State &state, Func func, Args &&...args) |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 37 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 38 | const int REPS = state.range(0); |
| 39 | |
| 40 | FunctionT<void(float *, float *)> function; |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 41 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 42 | Pointer<Float4> r = Pointer<Float>(function.Arg<0>()); |
| 43 | Pointer<Float4> a = Pointer<Float>(function.Arg<1>()); |
| 44 | |
| 45 | for(int i = 0; i < REPS; i++) |
| 46 | { |
| 47 | r[i] = func(a[i], args...); |
| 48 | } |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 49 | } |
| 50 | |
| 51 | auto routine = function("one"); |
| 52 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 53 | std::vector<float> r(REPS * 4); |
| 54 | std::vector<float> a(REPS * 4, 1.0f); |
| 55 | |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 56 | for(auto _ : state) |
| 57 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 58 | routine(r.data(), a.data()); |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 59 | } |
| 60 | } |
| 61 | |
| 62 | template<typename Func, class... Args> |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 63 | static void Transcendental2(benchmark::State &state, Func func, Args &&...args) |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 64 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 65 | const int REPS = state.range(0); |
| 66 | |
| 67 | FunctionT<void(float *, float *, float *)> function; |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 68 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 69 | Pointer<Float4> r = Pointer<Float>(function.Arg<0>()); |
| 70 | Pointer<Float4> a = Pointer<Float>(function.Arg<1>()); |
| 71 | Pointer<Float4> b = Pointer<Float>(function.Arg<2>()); |
| 72 | |
| 73 | for(int i = 0; i < REPS; i++) |
| 74 | { |
| 75 | r[i] = func(a[i], b[i], args...); |
| 76 | } |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | auto routine = function("two"); |
| 80 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 81 | std::vector<float> r(REPS * 4); |
| 82 | std::vector<float> a(REPS * 4, 0.456f); |
| 83 | std::vector<float> b(REPS * 4, 0.789f); |
| 84 | |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 85 | for(auto _ : state) |
| 86 | { |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 87 | routine(r.data(), a.data(), b.data()); |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 88 | } |
| 89 | } |
| 90 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 91 | // No operation; just copy the input to the output, for use as a baseline. |
| 92 | static Float4 Nop(RValue<Float4> x) |
| 93 | { |
| 94 | return x; |
| 95 | } |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 96 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 97 | static const int REPS = 10; |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 98 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 99 | BENCHMARK_CAPTURE(Transcendental1, Nop, Nop)->Arg(REPS); |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 100 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 101 | BENCHMARK_CAPTURE(Transcendental1, rr_Sin, rr::Sin)->Arg(REPS); |
| 102 | BENCHMARK_CAPTURE(Transcendental1, sw_Sin, sw::Sin)->Arg(REPS); |
| 103 | BENCHMARK_CAPTURE(Transcendental1, rr_Cos, rr::Cos)->Arg(REPS); |
| 104 | BENCHMARK_CAPTURE(Transcendental1, sw_Cos, sw::Cos)->Arg(REPS); |
| 105 | BENCHMARK_CAPTURE(Transcendental1, rr_Tan, rr::Tan)->Arg(REPS); |
| 106 | BENCHMARK_CAPTURE(Transcendental1, sw_Tan, sw::Tan)->Arg(REPS); |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 107 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 108 | BENCHMARK_CAPTURE(Transcendental1, rr_Asin, rr::Asin)->Arg(REPS); |
| 109 | BENCHMARK_CAPTURE(Transcendental1, sw_Asin_highpp, sw::Asin, false /* relaxedPrecision */)->Arg(REPS); |
| 110 | BENCHMARK_CAPTURE(Transcendental1, sw_Asin_relaxedp, sw::Asin, true /* relaxedPrecision */)->Arg(REPS); |
| 111 | BENCHMARK_CAPTURE(Transcendental1, rr_Acos, rr::Acos)->Arg(REPS); |
| 112 | BENCHMARK_CAPTURE(Transcendental1, sw_Acos_highp, sw::Acos, false /* relaxedPrecision */)->Arg(REPS); |
| 113 | BENCHMARK_CAPTURE(Transcendental1, sw_Acos_relaxedp, sw::Acos, true /* relaxedPrecision */)->Arg(REPS); |
Nicolas Capens | f7e7cc5 | 2022-02-06 08:51:05 -0500 | [diff] [blame] | 114 | |
Nicolas Capens | ece389a | 2022-02-06 09:49:19 -0500 | [diff] [blame] | 115 | BENCHMARK_CAPTURE(Transcendental1, rr_Atan, rr::Atan)->Arg(REPS); |
| 116 | BENCHMARK_CAPTURE(Transcendental1, sw_Atan, sw::Atan)->Arg(REPS); |
| 117 | BENCHMARK_CAPTURE(Transcendental1, rr_Sinh, rr::Sinh)->Arg(REPS); |
| 118 | BENCHMARK_CAPTURE(Transcendental1, sw_Sinh, sw::Sinh)->Arg(REPS); |
| 119 | BENCHMARK_CAPTURE(Transcendental1, rr_Cosh, rr::Cosh)->Arg(REPS); |
| 120 | BENCHMARK_CAPTURE(Transcendental1, sw_Cosh, sw::Cosh)->Arg(REPS); |
| 121 | BENCHMARK_CAPTURE(Transcendental1, rr_Tanh, rr::Tanh)->Arg(REPS); |
| 122 | BENCHMARK_CAPTURE(Transcendental1, sw_Tanh, sw::Tanh)->Arg(REPS); |
| 123 | |
| 124 | BENCHMARK_CAPTURE(Transcendental1, rr_Asinh, rr::Asinh)->Arg(REPS); |
| 125 | BENCHMARK_CAPTURE(Transcendental1, sw_Asinh, sw::Asinh)->Arg(REPS); |
| 126 | BENCHMARK_CAPTURE(Transcendental1, rr_Acosh, rr::Acosh)->Arg(REPS); |
| 127 | BENCHMARK_CAPTURE(Transcendental1, sw_Acosh, sw::Acosh)->Arg(REPS); |
| 128 | BENCHMARK_CAPTURE(Transcendental1, rr_Atanh, rr::Atanh)->Arg(REPS); |
| 129 | BENCHMARK_CAPTURE(Transcendental1, sw_Atanh, sw::Atanh)->Arg(REPS); |
| 130 | BENCHMARK_CAPTURE(Transcendental2, rr_Atan2, rr::Atan2)->Arg(REPS); |
| 131 | BENCHMARK_CAPTURE(Transcendental2, sw_Atan2, sw::Atan2)->Arg(REPS); |
| 132 | |
| 133 | BENCHMARK_CAPTURE(Transcendental2, rr_Pow, rr::Pow)->Arg(REPS); |
| 134 | BENCHMARK_CAPTURE(Transcendental2, sw_Pow, sw::Pow)->Arg(REPS); |
| 135 | BENCHMARK_CAPTURE(Transcendental1, rr_Exp, rr::Exp)->Arg(REPS); |
| 136 | BENCHMARK_CAPTURE(Transcendental1, sw_Exp, sw::Exp)->Arg(REPS); |
| 137 | BENCHMARK_CAPTURE(Transcendental1, rr_Log, rr::Log)->Arg(REPS); |
| 138 | BENCHMARK_CAPTURE(Transcendental1, sw_Log, sw::Log)->Arg(REPS); |
| 139 | BENCHMARK_CAPTURE(Transcendental1, rr_Exp2, LIFT(rr::Exp2))->Arg(REPS); |
| 140 | BENCHMARK_CAPTURE(Transcendental1, sw_Exp2, LIFT(sw::Exp2))->Arg(REPS); |
| 141 | BENCHMARK_CAPTURE(Transcendental1, rr_Log2, LIFT(rr::Log2))->Arg(REPS); |
| 142 | BENCHMARK_CAPTURE(Transcendental1, sw_Log2, LIFT(sw::Log2))->Arg(REPS); |
| 143 | |
| 144 | BENCHMARK_CAPTURE(Transcendental1, rr_Rcp_pp_exactAtPow2_true, LIFT(Rcp_pp), true)->Arg(REPS); |
| 145 | BENCHMARK_CAPTURE(Transcendental1, rr_Rcp_pp_exactAtPow2_false, LIFT(Rcp_pp), false)->Arg(REPS); |
| 146 | BENCHMARK_CAPTURE(Transcendental1, rr_RcpSqrt_pp, LIFT(RcpSqrt_pp))->Arg(REPS); |