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