[llvm] [XRay] Reserve memory space ahead-of-time when reading native format log (PR #76853)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 3 11:36:53 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-xray

Author: Min-Yih Hsu (mshockwave)

<details>
<summary>Changes</summary>

XRay used to struggle reading large log files. It turned out the bottleneck was primarily caused by the reallocation happens when appending log entries into a std::vector.
This patch reserves the memory space ahead-of-time since the number of entries is known for most cases. Making llvm-xray runs 1.8 times faster and uses 1.4 times less physical memory when reading large (~2.6GB) log files.

-------
Here are the benchmark numbers (benchmarking using hyperfine):
```
Benchmark 1: llvm-xray account --instr_map=../prog ./xray-log.prog.DnIfOu
  Time (mean ± σ):     20.606 s ±  1.127 s    [User: 9.467 s, System: 11.081 s]
  Range (min … max):   20.051 s … 23.296 s    10 runs

Benchmark 2: env XRAY_RESERVE_MEM=1 llvm-xray account --instr_map=../prog ./xray-log. prog.DnIfOu
  Time (mean ± σ):     11.238 s ±  0.017 s    [User: 6.544 s, System: 4.664 s]
  Range (min … max):   11.207 s … 11.261 s    10 runs

Summary
  env XRAY_RESERVE_MEM=1 llvm-xray account --instr_map=../prog ./xray-log.prog.DnIfOu ran
    1.83 ± 0.10 times faster than llvm-xray account --instr_map=../prog ./xray-log.prog.DnIfOu
```
Notes:
1. The XRay mode used here is `xray-basic`
2. `xray-log.prog.DnIfOu` is around 2.6GB
3. `XRAY_RESERVE_MEM` is a temporary environment variable solely for benchmarking purposes. We are NOT using it to toggle the improvement in this patch

---
Full diff: https://github.com/llvm/llvm-project/pull/76853.diff


1 Files Affected:

- (modified) llvm/lib/XRay/Trace.cpp (+3) 


``````````diff
diff --git a/llvm/lib/XRay/Trace.cpp b/llvm/lib/XRay/Trace.cpp
index b870adf565459f..74515b16417da3 100644
--- a/llvm/lib/XRay/Trace.cpp
+++ b/llvm/lib/XRay/Trace.cpp
@@ -51,6 +51,9 @@ Error loadNaiveFormatLog(StringRef Data, bool IsLittleEndian,
     return FileHeaderOrError.takeError();
   FileHeader = std::move(FileHeaderOrError.get());
 
+  size_t NumReservations = llvm::divideCeil(Reader.size() - OffsetPtr, 32U);
+  Records.reserve(NumReservations);
+
   // Each record after the header will be 32 bytes, in the following format:
   //
   //   (2)   uint16 : record type

``````````

</details>


https://github.com/llvm/llvm-project/pull/76853


More information about the llvm-commits mailing list