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 #include <random>
17
18 #include "ffrt_inner.h"
19 #include "common.h"
20
21 static constexpr uint64_t sz = 30; // 该值越大任务平均可并行度越大(平均并发度=sz/9)
22 static constexpr uint64_t iter = 1000000; // 该值越大迭代次数越多(减少测量误差)
23 static constexpr uint64_t depth = 10; // 该值越大子任务平均粒度越大(任务完成时间为泊松分布)(单位:微秒)
24
func(uint64_t x,uint64_t y)25 static inline uint64_t func(uint64_t x, uint64_t y)
26 {
27 std::mt19937_64 g(x - y);
28 uint64_t target = g() % (depth * 20);
29 uint64_t acc = 0;
30 while (acc % (depth * 20) != target) {
31 acc ^= g();
32 }
33 return acc;
34 }
35
GenerateIndexes(std::mt19937_64 & rnd,uint64_t (idx)[3])36 static inline void GenerateIndexes(std::mt19937_64& rnd, uint64_t(idx)[3])
37 {
38 bool duplicate = true;
39 while (duplicate) {
40 duplicate = false;
41 for (uint64_t i = 0; i < 3; i++) {
42 idx[i] = rnd() % sz;
43 for (uint64_t z = 0; z < i; z++) {
44 if (idx[z] == idx[i]) {
45 duplicate = true;
46 }
47 }
48 }
49 }
50 }
51
BenchmarkNative()52 static uint64_t BenchmarkNative()
53 {
54 uint64_t* arr = new uint64_t[sz];
55 std::mt19937_64 rnd(0);
56 // initialize the array
57 for (uint64_t i = 0; i < sz; i++) {
58 arr[i] = rnd();
59 }
60
61 // do computation randomly
62 TIME_BEGIN(t);
63 for (uint64_t i = 0; i < iter; i++) {
64 // generate 3 different indexes
65 uint64_t idx[3] = {};
66 GenerateIndexes(rnd, idx);
67
68 // submit a task
69 arr[idx[2]] = func(arr[idx[0]], arr[idx[1]]);
70 }
71 TIME_END_INFO(t, "benchmark_native");
72
73 // calculate FNV hash of the array
74 uint64_t hash = 14695981039346656037ULL;
75 for (uint64_t i = 0; i < sz; i++) {
76 hash = (hash * 1099511628211ULL) ^ arr[i];
77 }
78 delete[] arr;
79 return hash;
80 }
81
BenchmarkFFRT()82 static uint64_t BenchmarkFFRT()
83 {
84 uint64_t* arr = new uint64_t[sz];
85 std::mt19937_64 rnd(0);
86 // initialize the array
87 for (uint64_t i = 0; i < sz; i++) {
88 arr[i] = rnd();
89 }
90 // do computation randomly
91 TIME_BEGIN(t);
92 for (uint64_t i = 0; i < iter; i++) {
93 // generate 3 different indexes
94 uint64_t idx[3] = {};
95 GenerateIndexes(rnd, idx);
96
97 // submit a task
98 ffrt::submit([idx, &arr]() { arr[idx[2]] = func(arr[idx[0]], arr[idx[1]]); }, {&arr[idx[0]], &arr[idx[1]]},
99 {&arr[idx[2]]});
100 }
101 ffrt::wait();
102 TIME_END_INFO(t, "benchmark_ffrt");
103
104 // calculate FNV hash of the array
105 uint64_t hash = 14695981039346656037ULL;
106 for (uint64_t i = 0; i < sz; i++) {
107 hash = (hash * 1099511628211ULL) ^ arr[i];
108 }
109 delete[] arr;
110 return hash;
111 }
112
main()113 int main()
114 {
115 GetEnvs();
116 BenchmarkNative();
117 BenchmarkFFRT();
118 }