1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci 16484543d1Sopenharmony_ci#include <random> 17484543d1Sopenharmony_ci 18484543d1Sopenharmony_ci#include "ffrt_inner.h" 19484543d1Sopenharmony_ci#include "common.h" 20484543d1Sopenharmony_ci 21484543d1Sopenharmony_cistatic constexpr uint64_t sz = 30; // 该值越大任务平均可并行度越大(平均并发度=sz/9) 22484543d1Sopenharmony_cistatic constexpr uint64_t iter = 1000000; // 该值越大迭代次数越多(减少测量误差) 23484543d1Sopenharmony_cistatic constexpr uint64_t depth = 10; // 该值越大子任务平均粒度越大(任务完成时间为泊松分布)(单位:微秒) 24484543d1Sopenharmony_ci 25484543d1Sopenharmony_cistatic inline uint64_t func(uint64_t x, uint64_t y) 26484543d1Sopenharmony_ci{ 27484543d1Sopenharmony_ci std::mt19937_64 g(x - y); 28484543d1Sopenharmony_ci uint64_t target = g() % (depth * 20); 29484543d1Sopenharmony_ci uint64_t acc = 0; 30484543d1Sopenharmony_ci while (acc % (depth * 20) != target) { 31484543d1Sopenharmony_ci acc ^= g(); 32484543d1Sopenharmony_ci } 33484543d1Sopenharmony_ci return acc; 34484543d1Sopenharmony_ci} 35484543d1Sopenharmony_ci 36484543d1Sopenharmony_cistatic inline void GenerateIndexes(std::mt19937_64& rnd, uint64_t(idx)[3]) 37484543d1Sopenharmony_ci{ 38484543d1Sopenharmony_ci bool duplicate = true; 39484543d1Sopenharmony_ci while (duplicate) { 40484543d1Sopenharmony_ci duplicate = false; 41484543d1Sopenharmony_ci for (uint64_t i = 0; i < 3; i++) { 42484543d1Sopenharmony_ci idx[i] = rnd() % sz; 43484543d1Sopenharmony_ci for (uint64_t z = 0; z < i; z++) { 44484543d1Sopenharmony_ci if (idx[z] == idx[i]) { 45484543d1Sopenharmony_ci duplicate = true; 46484543d1Sopenharmony_ci } 47484543d1Sopenharmony_ci } 48484543d1Sopenharmony_ci } 49484543d1Sopenharmony_ci } 50484543d1Sopenharmony_ci} 51484543d1Sopenharmony_ci 52484543d1Sopenharmony_cistatic uint64_t BenchmarkNative() 53484543d1Sopenharmony_ci{ 54484543d1Sopenharmony_ci uint64_t* arr = new uint64_t[sz]; 55484543d1Sopenharmony_ci std::mt19937_64 rnd(0); 56484543d1Sopenharmony_ci // initialize the array 57484543d1Sopenharmony_ci for (uint64_t i = 0; i < sz; i++) { 58484543d1Sopenharmony_ci arr[i] = rnd(); 59484543d1Sopenharmony_ci } 60484543d1Sopenharmony_ci 61484543d1Sopenharmony_ci // do computation randomly 62484543d1Sopenharmony_ci TIME_BEGIN(t); 63484543d1Sopenharmony_ci for (uint64_t i = 0; i < iter; i++) { 64484543d1Sopenharmony_ci // generate 3 different indexes 65484543d1Sopenharmony_ci uint64_t idx[3] = {}; 66484543d1Sopenharmony_ci GenerateIndexes(rnd, idx); 67484543d1Sopenharmony_ci 68484543d1Sopenharmony_ci // submit a task 69484543d1Sopenharmony_ci arr[idx[2]] = func(arr[idx[0]], arr[idx[1]]); 70484543d1Sopenharmony_ci } 71484543d1Sopenharmony_ci TIME_END_INFO(t, "benchmark_native"); 72484543d1Sopenharmony_ci 73484543d1Sopenharmony_ci // calculate FNV hash of the array 74484543d1Sopenharmony_ci uint64_t hash = 14695981039346656037ULL; 75484543d1Sopenharmony_ci for (uint64_t i = 0; i < sz; i++) { 76484543d1Sopenharmony_ci hash = (hash * 1099511628211ULL) ^ arr[i]; 77484543d1Sopenharmony_ci } 78484543d1Sopenharmony_ci delete[] arr; 79484543d1Sopenharmony_ci return hash; 80484543d1Sopenharmony_ci} 81484543d1Sopenharmony_ci 82484543d1Sopenharmony_cistatic uint64_t BenchmarkFFRT() 83484543d1Sopenharmony_ci{ 84484543d1Sopenharmony_ci uint64_t* arr = new uint64_t[sz]; 85484543d1Sopenharmony_ci std::mt19937_64 rnd(0); 86484543d1Sopenharmony_ci // initialize the array 87484543d1Sopenharmony_ci for (uint64_t i = 0; i < sz; i++) { 88484543d1Sopenharmony_ci arr[i] = rnd(); 89484543d1Sopenharmony_ci } 90484543d1Sopenharmony_ci // do computation randomly 91484543d1Sopenharmony_ci TIME_BEGIN(t); 92484543d1Sopenharmony_ci for (uint64_t i = 0; i < iter; i++) { 93484543d1Sopenharmony_ci // generate 3 different indexes 94484543d1Sopenharmony_ci uint64_t idx[3] = {}; 95484543d1Sopenharmony_ci GenerateIndexes(rnd, idx); 96484543d1Sopenharmony_ci 97484543d1Sopenharmony_ci // submit a task 98484543d1Sopenharmony_ci ffrt::submit([idx, &arr]() { arr[idx[2]] = func(arr[idx[0]], arr[idx[1]]); }, {&arr[idx[0]], &arr[idx[1]]}, 99484543d1Sopenharmony_ci {&arr[idx[2]]}); 100484543d1Sopenharmony_ci } 101484543d1Sopenharmony_ci ffrt::wait(); 102484543d1Sopenharmony_ci TIME_END_INFO(t, "benchmark_ffrt"); 103484543d1Sopenharmony_ci 104484543d1Sopenharmony_ci // calculate FNV hash of the array 105484543d1Sopenharmony_ci uint64_t hash = 14695981039346656037ULL; 106484543d1Sopenharmony_ci for (uint64_t i = 0; i < sz; i++) { 107484543d1Sopenharmony_ci hash = (hash * 1099511628211ULL) ^ arr[i]; 108484543d1Sopenharmony_ci } 109484543d1Sopenharmony_ci delete[] arr; 110484543d1Sopenharmony_ci return hash; 111484543d1Sopenharmony_ci} 112484543d1Sopenharmony_ci 113484543d1Sopenharmony_ciint main() 114484543d1Sopenharmony_ci{ 115484543d1Sopenharmony_ci GetEnvs(); 116484543d1Sopenharmony_ci BenchmarkNative(); 117484543d1Sopenharmony_ci BenchmarkFFRT(); 118484543d1Sopenharmony_ci}