blob: 9dc43f7e2269e5567c1f322c9cc729fcf36aac86 [file]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <err.h>
#include <inttypes.h>
#include <malloc.h>
#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <algorithm>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
#include <android-base/file.h>
#include <android-base/strings.h>
#include <benchmark/benchmark.h>
#include <memory_trace/MemoryTrace.h>
#include <memory_trace/TraceInfo.h>
#include "File.h"
// Run a trace as if all of the allocations occurred in a single thread.
// This is not completely realistic, but it is a possible worst case that
// could happen in an app.
static void BenchmarkTrace(benchmark::State& state, const char* filename,
[[maybe_unused]] bool enable_decay_time) {
#if defined(__BIONIC__)
if (enable_decay_time) {
mallopt(M_DECAY_TIME, 1);
} else {
mallopt(M_DECAY_TIME, 0);
}
#endif
std::string full_filename(android::base::GetExecutableDirectory() + "/traces/" + filename);
static memory_trace::TraceInfo trace;
if (full_filename != trace.filename()) {
trace.Clear();
trace.Init(full_filename);
}
for (auto _ : state) {
uint64_t total_ns = trace.RunSingleThread();
state.SetIterationTime(total_ns / double(1000000000.0));
}
// Don't free the trace_data, it is cached. The last set of trace data
// will be leaked away.
}
#define BENCH_OPTIONS \
UseManualTime() \
->Unit(benchmark::kMicrosecond) \
->MinTime(15.0) \
->Repetitions(4) \
->ReportAggregatesOnly(true)
static void BM_angry_birds2_default(benchmark::State& state) {
BenchmarkTrace(state, "angry_birds2.zip", true);
}
BENCHMARK(BM_angry_birds2_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
static void BM_angry_birds2_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "angry_birds2.zip", false);
}
BENCHMARK(BM_angry_birds2_no_decay)->BENCH_OPTIONS;
#endif
static void BM_camera_default(benchmark::State& state) {
BenchmarkTrace(state, "camera.zip", true);
}
BENCHMARK(BM_camera_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
static void BM_camera_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "camera.zip", false);
}
BENCHMARK(BM_camera_no_decay)->BENCH_OPTIONS;
#endif
static void BM_candy_crush_saga_default(benchmark::State& state) {
BenchmarkTrace(state, "candy_crush_saga.zip", true);
}
BENCHMARK(BM_candy_crush_saga_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
static void BM_candy_crush_saga_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "candy_crush_saga.zip", false);
}
BENCHMARK(BM_candy_crush_saga_no_decay)->BENCH_OPTIONS;
#endif
void BM_gmail_default(benchmark::State& state) {
BenchmarkTrace(state, "gmail.zip", true);
}
BENCHMARK(BM_gmail_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_gmail_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "gmail.zip", false);
}
BENCHMARK(BM_gmail_no_decay)->BENCH_OPTIONS;
#endif
void BM_maps_default(benchmark::State& state) {
BenchmarkTrace(state, "maps.zip", true);
}
BENCHMARK(BM_maps_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_maps_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "maps.zip", false);
}
BENCHMARK(BM_maps_no_decay)->BENCH_OPTIONS;
#endif
void BM_photos_default(benchmark::State& state) {
BenchmarkTrace(state, "photos.zip", true);
}
BENCHMARK(BM_photos_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_photos_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "photos.zip", false);
}
BENCHMARK(BM_photos_no_decay)->BENCH_OPTIONS;
#endif
void BM_pubg_default(benchmark::State& state) {
BenchmarkTrace(state, "pubg.zip", true);
}
BENCHMARK(BM_pubg_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_pubg_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "pubg.zip", false);
}
BENCHMARK(BM_pubg_no_decay)->BENCH_OPTIONS;
#endif
void BM_surfaceflinger_default(benchmark::State& state) {
BenchmarkTrace(state, "surfaceflinger.zip", true);
}
BENCHMARK(BM_surfaceflinger_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_surfaceflinger_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "surfaceflinger.zip", false);
}
BENCHMARK(BM_surfaceflinger_no_decay)->BENCH_OPTIONS;
#endif
void BM_system_server_default(benchmark::State& state) {
BenchmarkTrace(state, "system_server.zip", true);
}
BENCHMARK(BM_system_server_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_system_server_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "system_server.zip", false);
}
BENCHMARK(BM_system_server_no_decay)->BENCH_OPTIONS;
#endif
void BM_systemui_default(benchmark::State& state) {
BenchmarkTrace(state, "systemui.zip", true);
}
BENCHMARK(BM_systemui_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_systemui_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "systemui.zip", false);
}
BENCHMARK(BM_systemui_no_decay)->BENCH_OPTIONS;
#endif
void BM_youtube_default(benchmark::State& state) {
BenchmarkTrace(state, "youtube.zip", true);
}
BENCHMARK(BM_youtube_default)->BENCH_OPTIONS;
#if defined(__BIONIC__)
void BM_youtube_no_decay(benchmark::State& state) {
BenchmarkTrace(state, "youtube.zip", false);
}
BENCHMARK(BM_youtube_no_decay)->BENCH_OPTIONS;
#endif
int main(int argc, char** argv) {
std::vector<char*> args;
args.push_back(argv[0]);
// Look for the --cpu=XX option.
for (int i = 1; i < argc; i++) {
if (strncmp(argv[i], "--cpu=", 6) == 0) {
char* endptr;
int cpu = strtol(&argv[i][6], &endptr, 10);
if (argv[i][0] == '\0' || endptr == nullptr || *endptr != '\0') {
printf("Invalid format of --cpu option, '%s' must be an integer value.\n", argv[i] + 6);
return 1;
}
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
if (errno == EINVAL) {
printf("Invalid cpu %d\n", cpu);
return 1;
}
perror("sched_setaffinity failed");
return 1;
}
printf("Locking to cpu %d\n", cpu);
} else {
args.push_back(argv[i]);
}
}
argc = args.size();
::benchmark::Initialize(&argc, args.data());
if (::benchmark::ReportUnrecognizedArguments(argc, args.data())) return 1;
::benchmark::RunSpecifiedBenchmarks();
}