1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker * All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker *
5*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*8d67ca89SAndroid Build Coastguard Worker * are met:
8*8d67ca89SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
9*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*8d67ca89SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright
11*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
12*8d67ca89SAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
13*8d67ca89SAndroid Build Coastguard Worker * distribution.
14*8d67ca89SAndroid Build Coastguard Worker *
15*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*8d67ca89SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*8d67ca89SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*8d67ca89SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*8d67ca89SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*8d67ca89SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*8d67ca89SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*8d67ca89SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*8d67ca89SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*8d67ca89SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*8d67ca89SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
27*8d67ca89SAndroid Build Coastguard Worker */
28*8d67ca89SAndroid Build Coastguard Worker
29*8d67ca89SAndroid Build Coastguard Worker #include <err.h>
30*8d67ca89SAndroid Build Coastguard Worker #include <malloc.h>
31*8d67ca89SAndroid Build Coastguard Worker #include <stdint.h>
32*8d67ca89SAndroid Build Coastguard Worker
33*8d67ca89SAndroid Build Coastguard Worker #include <map>
34*8d67ca89SAndroid Build Coastguard Worker #include <unordered_map>
35*8d67ca89SAndroid Build Coastguard Worker #include <vector>
36*8d67ca89SAndroid Build Coastguard Worker
37*8d67ca89SAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
38*8d67ca89SAndroid Build Coastguard Worker #include "util.h"
39*8d67ca89SAndroid Build Coastguard Worker
40*8d67ca89SAndroid Build Coastguard Worker #include <android-base/strings.h>
41*8d67ca89SAndroid Build Coastguard Worker
42*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
43*8d67ca89SAndroid Build Coastguard Worker
44*8d67ca89SAndroid Build Coastguard Worker #include <meminfo/procmeminfo.h>
45*8d67ca89SAndroid Build Coastguard Worker #include <procinfo/process_map.h>
46*8d67ca89SAndroid Build Coastguard Worker
Gather(uint64_t * rss_bytes)47*8d67ca89SAndroid Build Coastguard Worker static void Gather(uint64_t* rss_bytes) {
48*8d67ca89SAndroid Build Coastguard Worker android::meminfo::ProcMemInfo proc_mem(getpid());
49*8d67ca89SAndroid Build Coastguard Worker const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
50*8d67ca89SAndroid Build Coastguard Worker for (auto& vma : maps) {
51*8d67ca89SAndroid Build Coastguard Worker if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
52*8d67ca89SAndroid Build Coastguard Worker android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
53*8d67ca89SAndroid Build Coastguard Worker android::meminfo::Vma update_vma(vma);
54*8d67ca89SAndroid Build Coastguard Worker if (!proc_mem.FillInVmaStats(update_vma)) {
55*8d67ca89SAndroid Build Coastguard Worker err(1, "FillInVmaStats failed");
56*8d67ca89SAndroid Build Coastguard Worker }
57*8d67ca89SAndroid Build Coastguard Worker *rss_bytes += update_vma.usage.rss;
58*8d67ca89SAndroid Build Coastguard Worker }
59*8d67ca89SAndroid Build Coastguard Worker }
60*8d67ca89SAndroid Build Coastguard Worker }
61*8d67ca89SAndroid Build Coastguard Worker #endif
62*8d67ca89SAndroid Build Coastguard Worker
63*8d67ca89SAndroid Build Coastguard Worker template <typename MapType>
MapBenchmark(benchmark::State & state,size_t num_elements)64*8d67ca89SAndroid Build Coastguard Worker static void MapBenchmark(benchmark::State& state, size_t num_elements) {
65*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
66*8d67ca89SAndroid Build Coastguard Worker uint64_t rss_bytes = 0;
67*8d67ca89SAndroid Build Coastguard Worker #endif
68*8d67ca89SAndroid Build Coastguard Worker
69*8d67ca89SAndroid Build Coastguard Worker for (auto _ : state) {
70*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
71*8d67ca89SAndroid Build Coastguard Worker state.PauseTiming();
72*8d67ca89SAndroid Build Coastguard Worker mallopt(M_PURGE_ALL, 0);
73*8d67ca89SAndroid Build Coastguard Worker uint64_t rss_bytes_before = 0;
74*8d67ca89SAndroid Build Coastguard Worker Gather(&rss_bytes_before);
75*8d67ca89SAndroid Build Coastguard Worker state.ResumeTiming();
76*8d67ca89SAndroid Build Coastguard Worker #endif
77*8d67ca89SAndroid Build Coastguard Worker MapType map;
78*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < num_elements; i++) {
79*8d67ca89SAndroid Build Coastguard Worker map[i][0] = 0;
80*8d67ca89SAndroid Build Coastguard Worker }
81*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
82*8d67ca89SAndroid Build Coastguard Worker state.PauseTiming();
83*8d67ca89SAndroid Build Coastguard Worker mallopt(M_PURGE_ALL, 0);
84*8d67ca89SAndroid Build Coastguard Worker Gather(&rss_bytes);
85*8d67ca89SAndroid Build Coastguard Worker // Try and record only the memory used in the map.
86*8d67ca89SAndroid Build Coastguard Worker rss_bytes -= rss_bytes_before;
87*8d67ca89SAndroid Build Coastguard Worker state.ResumeTiming();
88*8d67ca89SAndroid Build Coastguard Worker #endif
89*8d67ca89SAndroid Build Coastguard Worker }
90*8d67ca89SAndroid Build Coastguard Worker
91*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
92*8d67ca89SAndroid Build Coastguard Worker double rss_mb = (rss_bytes / static_cast<double>(state.iterations())) / 1024.0 / 1024.0;
93*8d67ca89SAndroid Build Coastguard Worker state.counters["RSS_MB"] = rss_mb;
94*8d67ca89SAndroid Build Coastguard Worker #endif
95*8d67ca89SAndroid Build Coastguard Worker }
96*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_8(benchmark::State & state)97*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_8(benchmark::State& state) {
98*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[8]>>(state, 1000000);
99*8d67ca89SAndroid Build Coastguard Worker }
100*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_8);
101*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_16(benchmark::State & state)102*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_16(benchmark::State& state) {
103*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[16]>>(state, 1000000);
104*8d67ca89SAndroid Build Coastguard Worker }
105*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_16);
106*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_32(benchmark::State & state)107*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_32(benchmark::State& state) {
108*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[32]>>(state, 1000000);
109*8d67ca89SAndroid Build Coastguard Worker }
110*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_32);
111*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_64(benchmark::State & state)112*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_64(benchmark::State& state) {
113*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[64]>>(state, 1000000);
114*8d67ca89SAndroid Build Coastguard Worker }
115*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_64);
116*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_96(benchmark::State & state)117*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_96(benchmark::State& state) {
118*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[96]>>(state, 1000000);
119*8d67ca89SAndroid Build Coastguard Worker }
120*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_96);
121*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_128(benchmark::State & state)122*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_128(benchmark::State& state) {
123*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[128]>>(state, 500000);
124*8d67ca89SAndroid Build Coastguard Worker }
125*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_128);
126*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_256(benchmark::State & state)127*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_256(benchmark::State& state) {
128*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[256]>>(state, 500000);
129*8d67ca89SAndroid Build Coastguard Worker }
130*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_256);
131*8d67ca89SAndroid Build Coastguard Worker
BM_std_map_512(benchmark::State & state)132*8d67ca89SAndroid Build Coastguard Worker static void BM_std_map_512(benchmark::State& state) {
133*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::map<uint64_t, char[512]>>(state, 500000);
134*8d67ca89SAndroid Build Coastguard Worker }
135*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_map_512);
136*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_8(benchmark::State & state)137*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_8(benchmark::State& state) {
138*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[8]>>(state, 1000000);
139*8d67ca89SAndroid Build Coastguard Worker }
140*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_8);
141*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_16(benchmark::State & state)142*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_16(benchmark::State& state) {
143*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[16]>>(state, 1000000);
144*8d67ca89SAndroid Build Coastguard Worker }
145*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_16);
146*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_32(benchmark::State & state)147*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_32(benchmark::State& state) {
148*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[32]>>(state, 1000000);
149*8d67ca89SAndroid Build Coastguard Worker }
150*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_32);
151*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_64(benchmark::State & state)152*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_64(benchmark::State& state) {
153*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[64]>>(state, 1000000);
154*8d67ca89SAndroid Build Coastguard Worker }
155*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_64);
156*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_96(benchmark::State & state)157*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_96(benchmark::State& state) {
158*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[96]>>(state, 1000000);
159*8d67ca89SAndroid Build Coastguard Worker }
160*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_96);
161*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_128(benchmark::State & state)162*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_128(benchmark::State& state) {
163*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[128]>>(state, 500000);
164*8d67ca89SAndroid Build Coastguard Worker }
165*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_128);
166*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_256(benchmark::State & state)167*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_256(benchmark::State& state) {
168*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[256]>>(state, 500000);
169*8d67ca89SAndroid Build Coastguard Worker }
170*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_256);
171*8d67ca89SAndroid Build Coastguard Worker
BM_std_unordered_map_512(benchmark::State & state)172*8d67ca89SAndroid Build Coastguard Worker static void BM_std_unordered_map_512(benchmark::State& state) {
173*8d67ca89SAndroid Build Coastguard Worker MapBenchmark<std::unordered_map<uint64_t, char[512]>>(state, 500000);
174*8d67ca89SAndroid Build Coastguard Worker }
175*8d67ca89SAndroid Build Coastguard Worker BIONIC_BENCHMARK(BM_std_unordered_map_512);
176