blob: 79774c3526a04a0ed8cd75e40d1e00db4b6f4d5e [file] [log] [blame]
//===-- Benchmark ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "LibcMemoryBenchmarkMain.h"
#include "JSON.h"
#include "LibcBenchmark.h"
#include "LibcMemoryBenchmark.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
namespace llvm {
namespace libc_benchmarks {
static cl::opt<std::string>
Configuration("conf", cl::desc("Specify configuration filename"),
cl::value_desc("filename"), cl::init(""));
static cl::opt<std::string> Output("o", cl::desc("Specify output filename"),
cl::value_desc("filename"), cl::init("-"));
extern std::unique_ptr<BenchmarkRunner>
getRunner(const StudyConfiguration &Conf);
void Main() {
#ifndef NDEBUG
static_assert(
false,
"For reproducibility benchmarks should not be compiled in DEBUG mode.");
#endif
checkRequirements();
ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
MemoryBuffer::getFileOrSTDIN(Configuration);
if (!MB)
report_fatal_error(
Twine("Could not open configuration file: ").concat(Configuration));
auto ErrorOrStudy = ParseJsonStudy((*MB)->getBuffer());
if (!ErrorOrStudy)
report_fatal_error(ErrorOrStudy.takeError());
const auto StudyPrototype = *ErrorOrStudy;
Study S;
S.Host = HostState::get();
S.Options = StudyPrototype.Options;
S.Configuration = StudyPrototype.Configuration;
const auto Runs = S.Configuration.Runs;
const auto &SR = S.Configuration.Size;
std::unique_ptr<BenchmarkRunner> Runner = getRunner(S.Configuration);
const size_t TotalSteps =
Runner->getFunctionNames().size() * Runs * ((SR.To - SR.From) / SR.Step);
size_t Steps = 0;
for (auto FunctionName : Runner->getFunctionNames()) {
FunctionMeasurements FM;
FM.Name = std::string(FunctionName);
for (size_t Run = 0; Run < Runs; ++Run) {
for (uint32_t Size = SR.From; Size <= SR.To; Size += SR.Step) {
const auto Result = Runner->benchmark(S.Options, FunctionName, Size);
Measurement Measurement;
Measurement.Runtime = Result.BestGuess;
Measurement.Size = Size;
FM.Measurements.push_back(Measurement);
outs() << format("%3d%% run: %2d / %2d size: %5d ",
(Steps * 100 / TotalSteps), Run, Runs, Size)
<< FunctionName
<< " \r";
++Steps;
}
}
S.Functions.push_back(std::move(FM));
}
std::error_code EC;
raw_fd_ostream FOS(Output, EC);
if (EC)
report_fatal_error(Twine("Could not open file: ")
.concat(EC.message())
.concat(", ")
.concat(Output));
json::OStream JOS(FOS);
SerializeToJson(S, JOS);
}
} // namespace libc_benchmarks
} // namespace llvm
int main(int argc, char **argv) {
llvm::cl::ParseCommandLineOptions(argc, argv);
llvm::libc_benchmarks::Main();
return EXIT_SUCCESS;
}