[PATCH] D94555: [LLD][COFF] Avoid std::vector resizes during type merging
Alexandre Ganea via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 12 14:28:13 PST 2021
aganea created this revision.
aganea requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
As discussed in https://reviews.llvm.org/D87805#2491679 the `MergedInfo::recs` vector can get quite large and resizing it while remapping types creates unnecessary copies and virtual memory page faults.
This patch saves consistently approx. 0.6 sec (out of 18 sec).
With 12 hyper-threads:
Benchmark #1: before\lld-link.exe @link.rsp /threads:12
Time (mean ± σ): 17.939 s ± 1.215 s [User: 2.7 ms, System: 3.5 ms]
Range (min … max): 15.537 s … 18.597 s 10 runs
Benchmark #2: after\lld-link.exe @link.rsp /threads:12
Time (mean ± σ): 17.298 s ± 1.511 s [User: 1.4 ms, System: 8.9 ms]
Range (min … max): 15.512 s … 18.513 s 10 runs
With 36 hyper-threads (thus using only one CPU socket):
Benchmark #1: before\lld-link.exe @link.rsp
Time (mean ± σ): 18.085 s ± 0.764 s [User: 2.7 ms, System: 3.3 ms]
Range (min … max): 15.918 s … 18.444 s 10 runs
Benchmark #2: after\lld-link.exe @link.rsp
Time (mean ± σ): 17.453 s ± 1.147 s [User: 2.7 ms, System: 8.7 ms]
Range (min … max): 15.766 s … 18.246 s 10 runs
Summary
'f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\lld-link.exe @link.rsp' ran
1.04 ± 0.08 times faster than 'f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\old\lld-link.exe @link.rsp'
F:\aganea\anvilp\games\ack\projects\win64>hyperfine --show-output "f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\old\lld-link.exe @link.rsp /threads:36" "f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\lld-link.exe @link.rsp /threads:36"
Benchmark #1: f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\old\lld-link.exe @link.rsp /threads:36
Time (mean ± σ): 17.787 s ± 0.747 s [User: 4.2 ms, System: 5.6 ms]
Range (min … max): 15.666 s … 18.059 s 10 runs
Benchmark #2: f:\aganea\llvm-project\buildninjaRelRpMalloc2\bin\lld-link.exe @link.rsp /threads:36
Time (mean ± σ): 17.102 s ± 1.323 s [User: 2.6 ms, System: 4.0 ms]
Range (min … max): 15.175 s … 18.023 s 10 runs
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D94555
Files:
lld/COFF/DebugTypes.cpp
lld/COFF/DebugTypes.h
Index: lld/COFF/DebugTypes.h
===================================================================
--- lld/COFF/DebugTypes.h
+++ lld/COFF/DebugTypes.h
@@ -72,6 +72,9 @@
void remapRecord(MutableArrayRef<uint8_t> rec,
ArrayRef<llvm::codeview::TiReference> typeRefs);
+ void computeTypeRecordSize(llvm::codeview::CVType ty, unsigned &nbTpiRecs,
+ unsigned &nbIpiRecs);
+
void mergeTypeRecord(TypeIndex curIndex, llvm::codeview::CVType ty);
// Merge the type records listed in uniqueTypes. beginIndex is the TypeIndex
Index: lld/COFF/DebugTypes.cpp
===================================================================
--- lld/COFF/DebugTypes.cpp
+++ lld/COFF/DebugTypes.cpp
@@ -620,6 +620,17 @@
});
}
+void TpiSource::computeTypeRecordSize(CVType ty, unsigned &nbTpiRecs,
+ unsigned &nbIpiRecs) {
+ assert(ty.length() <= codeview::MaxRecordLength);
+ size_t newSize = alignTo(ty.length(), 4);
+
+ // Decide if the merged type goes into TPI or IPI.
+ bool isItem = isIdRecord(ty.kind());
+
+ (isItem ? nbIpiRecs : nbTpiRecs) += newSize;
+}
+
void TpiSource::mergeTypeRecord(TypeIndex curIndex, CVType ty) {
// Decide if the merged type goes into TPI or IPI.
bool isItem = isIdRecord(ty.kind());
@@ -679,6 +690,24 @@
auto nextUniqueIndex = uniqueTypes.begin();
assert(mergedTpi.recs.empty());
assert(mergedIpi.recs.empty());
+
+ // Pre-compute the number of elements in advance to avoid std::vector resizes.
+ unsigned nbTpiRecs = 0;
+ unsigned nbIpiRecs = 0;
+ forEachTypeChecked(typeRecords, [&](const CVType &ty) {
+ if (nextUniqueIndex != uniqueTypes.end() &&
+ *nextUniqueIndex == ghashIndex) {
+ computeTypeRecordSize(ty, nbTpiRecs, nbIpiRecs);
+ ++nextUniqueIndex;
+ }
+ ++ghashIndex;
+ });
+ mergedTpi.recs.reserve(nbTpiRecs);
+ mergedIpi.recs.reserve(nbIpiRecs);
+
+ // Do the actual type merge.
+ ghashIndex = 0;
+ nextUniqueIndex = uniqueTypes.begin();
forEachTypeChecked(typeRecords, [&](const CVType &ty) {
if (nextUniqueIndex != uniqueTypes.end() &&
*nextUniqueIndex == ghashIndex) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D94555.316241.patch
Type: text/x-patch
Size: 2168 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210112/f1907bb4/attachment-0001.bin>
More information about the llvm-commits
mailing list