1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 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 */ 15 16#ifndef BENCHMARKS_COMMON 17#define BENCHMARKS_COMMON 18 19#include <chrono> 20#include <cstdlib> 21#include <inttypes.h> 22#include "ffrt_inner.h" 23 24size_t COMPUTE_TIME_US = 0; 25uint64_t REPEAT = 1; 26uint64_t PREHOT_FFRT = 1; 27uint64_t FIB_NUM = 0; 28 29#define CLOCK std::chrono::steady_clock::now() 30#define TIME_BEGIN(t) auto __##t##_start = CLOCK 31#define TIME_END(t) \ 32 do { \ 33 decltype(__##t##_start) __##t##_cur = CLOCK; \ 34 ("%-12s:%-4d %6lu us\n", __FILE__, __LINE__, \ 35 long(std::chrono::duration_cast<std::chrono::microseconds>(__##t##_cur - __##t##_start).count())); \ 36 } while (0) 37#define TIME_END_INFO(t, info) \ 38 do { \ 39 decltype(__##t##_start) __##t##_cur = CLOCK; \ 40 printf("%-12s:%-4d %s %6lu us\n", __FILE__, __LINE__, info, \ 41 long(std::chrono::duration_cast<std::chrono::microseconds>(__##t##_cur - __##t##_start).count())); \ 42 } while (0) 43 44#define GET_ENV(name, var, default) \ 45 do { \ 46 auto __get_env_##name = getenv(#name); \ 47 var = __get_env_##name ? atoi(__get_env_##name) : default; \ 48 printf(#name " = %" PRIu64 "\n", (uint64_t)(var)); \ 49 } while (0) 50 51#define EXPECT(cond) \ 52 if (!(cond)) { \ 53 printf(#cond " check failed\n"); \ 54 } 55 56static inline void simulate_task_compute_time(size_t us) 57{ 58 auto start = std::chrono::steady_clock::now(); 59 size_t passed = 0; 60 while (passed < us) { 61 passed = 62 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count(); 63 } 64} 65 66static void FibFFRT(int x, int& y) 67{ 68 if (x <= 1) { 69 y = x; 70 } else { 71 int y1; 72 int y2; 73 ffrt::submit([&]() { FibFFRT(x - 1, y1); }, {&x}, {&y1}); 74 ffrt::submit([&]() { FibFFRT(x - 2, y2); }, {&x}, {&y2}); 75 ffrt::wait({&y1, &y2}); 76 y = y1 + y2; 77 } 78 simulate_task_compute_time(COMPUTE_TIME_US); 79} 80 81void PreHotFFRT(void) 82{ 83 if (!PREHOT_FFRT) { 84 return; 85 } 86 int output; 87 ffrt::submit([&]() { FibFFRT(20, output); }, {}, {&output}); 88 ffrt::wait({&output}); 89} 90 91void GetEnvs(void) 92{ 93 GET_ENV(COMPUTE_TIME_US, COMPUTE_TIME_US, 0); 94 GET_ENV(REPEAT, REPEAT, 1); 95 GET_ENV(PREHOT_FFRT, PREHOT_FFRT, 0); 96 GET_ENV(FIB_NUM, FIB_NUM, 5); 97} 98 99static inline void completely_paralle(uint32_t count, uint32_t duration, int64_t& time) 100{ 101 uint32_t loop = count; 102 auto start = std::chrono::steady_clock::now(); 103 while (loop--) { 104 ffrt::submit([&]() { simulate_task_compute_time(duration); }, {}, {}); 105 } 106 ffrt::wait(); 107 time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count(); 108} 109 110static inline void completely_serial(uint32_t count, uint32_t duration, int64_t& time) 111{ 112 uint32_t x = 0; 113 uint32_t loop = count; 114 auto start = std::chrono::steady_clock::now(); 115 while (loop--) { 116 ffrt::submit([&]() { simulate_task_compute_time(duration); }, {&x}, {&x}); 117 } 118 ffrt::wait(); 119 time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count(); 120} 121static inline void single_thread(uint32_t count, uint32_t duration, int64_t& time) 122{ 123 uint32_t loop = count; 124 auto start = std::chrono::steady_clock::now(); 125 while (loop--) { 126 simulate_task_compute_time(duration); 127 } 128 time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count(); 129} 130#endif