1 //===-- Benchmark memcpy implementation -----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "LibcBenchmark.h"
10 #include "LibcMemoryBenchmark.h"
11 #include "LibcMemoryBenchmarkMain.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include <memory>
15
16 namespace __llvm_libc {
17 extern void *memcpy(void *__restrict, const void *__restrict, size_t);
18 } // namespace __llvm_libc
19
20 namespace llvm {
21 namespace libc_benchmarks {
22
23 // The context encapsulates the buffers, parameters and the measure.
24 struct MemcpyContext : public BenchmarkRunner {
25 using FunctionPrototype = void *(*)(void *, const void *, size_t);
26
27 struct ParameterType {
28 uint16_t SrcOffset = 0;
29 uint16_t DstOffset = 0;
30 };
31
MemcpyContextllvm::libc_benchmarks::MemcpyContext32 explicit MemcpyContext(const StudyConfiguration &Conf)
33 : OD(Conf), SrcBuffer(Conf.BufferSize), DstBuffer(Conf.BufferSize),
34 PP(*this) {}
35
36 // Needed by the ParameterProvider to update the current batch of parameter.
Randomizellvm::libc_benchmarks::MemcpyContext37 void Randomize(MutableArrayRef<ParameterType> Parameters) {
38 for (auto &P : Parameters) {
39 P.DstOffset = OD(Gen);
40 P.SrcOffset = OD(Gen);
41 }
42 }
43
getFunctionNamesllvm::libc_benchmarks::MemcpyContext44 ArrayRef<StringRef> getFunctionNames() const override {
45 static std::array<StringRef, 1> kFunctionNames = {"memcpy"};
46 return kFunctionNames;
47 }
48
benchmarkllvm::libc_benchmarks::MemcpyContext49 BenchmarkResult benchmark(const BenchmarkOptions &Options,
50 StringRef FunctionName, size_t Size) override {
51 FunctionPrototype Function =
52 StringSwitch<FunctionPrototype>(FunctionName).Case("memcpy", &::memcpy);
53 return llvm::libc_benchmarks::benchmark(
54 Options, PP, [this, Function, Size](ParameterType p) {
55 Function(DstBuffer + p.DstOffset, SrcBuffer + p.SrcOffset, Size);
56 return DstBuffer + p.DstOffset;
57 });
58 }
59
60 private:
61 std::default_random_engine Gen;
62 OffsetDistribution OD;
63 AlignedBuffer SrcBuffer;
64 AlignedBuffer DstBuffer;
65 SmallParameterProvider<MemcpyContext> PP;
66 };
67
getRunner(const StudyConfiguration & Conf)68 std::unique_ptr<BenchmarkRunner> getRunner(const StudyConfiguration &Conf) {
69 return std::make_unique<MemcpyContext>(Conf);
70 }
71
72 } // namespace libc_benchmarks
73 } // namespace llvm
74