-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[lld][MachO] Follow-up to use madvise() for threaded file page-in. #157917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-support @llvm/pr-subscribers-lld-macho Author: John Holdsworth (johnno1962) ChangesFurther to #147134 (comment), switch to use the madvise() api to page in mmap'd files. Full diff: https://github.com/llvm/llvm-project/pull/157917.diff 1 Files Affected:
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 3db638e1ead96..2635c82a53448 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -53,6 +53,8 @@
#include "llvm/TextAPI/Architecture.h"
#include "llvm/TextAPI/PackedVersion.h"
+#include <sys/mman.h>
+
using namespace llvm;
using namespace llvm::MachO;
using namespace llvm::object;
@@ -334,11 +336,10 @@ class SerialBackgroundQueue {
// This code forces the page-ins on multiple threads so
// the process is not stalled waiting on disk buffer i/o.
void multiThreadedPageInBackground(DeferredFiles &deferred) {
- static const size_t pageSize = Process::getPageSizeEstimate();
static const size_t largeArchive = 10 * 1024 * 1024;
#ifndef NDEBUG
using namespace std::chrono;
- std::atomic_int numDeferedFilesTouched = 0;
+ std::atomic_int numDeferedFilesAdvised = 0;
static std::atomic_uint64_t totalBytes = 0;
auto t0 = high_resolution_clock::now();
#endif
@@ -349,13 +350,11 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
return;
#ifndef NDEBUG
totalBytes += buff.size();
- numDeferedFilesTouched += 1;
+ numDeferedFilesAdvised += 1;
#endif
- // Reference all file's mmap'd pages to load them into memory.
- for (const char *page = buff.data(), *end = page + buff.size(); page < end;
- page += pageSize)
- LLVM_ATTRIBUTE_UNUSED volatile char t = *page;
+ // Advise that mmap'd files should be loaded into memory.
+ madvise((void *)buff.data(), buff.size(), MADV_WILLNEED);
};
#if LLVM_ENABLE_THREADS
{ // Create scope for waiting for the taskGroup
@@ -376,7 +375,7 @@ void multiThreadedPageInBackground(DeferredFiles &deferred) {
auto dt = high_resolution_clock::now() - t0;
if (Process::GetEnv("LLD_MULTI_THREAD_PAGE"))
llvm::dbgs() << "multiThreadedPageIn " << totalBytes << "/"
- << numDeferedFilesTouched << "/" << deferred.size() << "/"
+ << numDeferedFilesAdvised << "/" << deferred.size() << "/"
<< duration_cast<milliseconds>(dt).count() / 1000. << "\n";
#endif
}
|
dc9ac78
to
0687bce
Compare
0687bce
to
65e433c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
✅ With the latest revision this PR passed the C/C++ code formatter. |
01fd8d8
to
1f188be
Compare
1f188be
to
59e77f5
Compare
d653ae5
to
298380e
Compare
5be953a
to
b87e01e
Compare
b87e01e
to
64d5be0
Compare
1636d63
to
11711bb
Compare
I've included changes to two additional files to counter the performance regression of 2 seconds from 85cd3d9 for the linker when using the --worker-threads option due to not mmap()ing many input files. Binary object and archive files don't need to be null terminated. This seemed the least intrusive change. |
a8a7d65
to
be7af98
Compare
Another more speculative commit, multi-threading the opening of files by making macho::readFile() thread safe. Another 1.5 second (10%) reduction of time spent linking the example Chrome task which originally took 25 seconds. Thu Sep 18 11:07:02 be7af98 0m10.548s 0m10.581s 0m10.748s 0m10.485s 0m10.486s 0m10.619s 0m10.434s 0m10.682s |
This reverts commit be7af98.
9d47440
to
bdf8995
Compare
5a39e60
to
94598b5
Compare
94598b5
to
d4ebd0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a general comment for this PR, we avoid usually #ifdefs
in code. I think you can write this entire PR without ever using any #ifdef LLVM_ENABLE_THREADS
; either by leaving the code active at all times, or by using existing LLVM APIs that already handle that flag. An example of this is llvm::get_threadpool_strategy
which falls back to not using threads when LLVM_ENABLE_THREADS
is set. Similarly, ThreadPool
does the same thing. Also, all places where we test for if (config->readWorkers)
we could also test for llvm_is_multithreaded()
.
db007c8
to
a5fda52
Compare
@aganea, I've removed all the #if which were intended to show clearly where the new code paths are; In practice you can tell by looking for |
a5fda52
to
ba7dedc
Compare
This reverts commit c91dd39.
This would fix an issue on our buildbot, any chance of getting another round of review so we can eventually merge this? |
Also expand the #ifdef to remove unused code in this configuration. As suggested in llvm#147134 (comment). I have also: * Expanded the error message to explain why it's not allowed. * Added a test for the error. * Marked the original test as unsupported when threads are disabled. Fixes issues we have had on Armv8 with threading disabled where this test would crash every so often. This change will hopefully be superseded by llvm#157917, but that has been in review a long time and I want to make the bot stable again. I could just disable the test, but I'd like lld to function properly in general in the meantime too. Co-authored-by: John Holdsworth <[email protected]>
…163925) Also expand the #ifdef to remove unused code in this configuration. As suggested in #147134 (comment). I have also: * Expanded the error message to explain why it's not allowed. * Added a test for the error. * Marked the original test as unsupported when threads are disabled. Fixes issues we have had on Armv8 with threading disabled where this test would crash every so often. This change will hopefully be superseded by #157917, but that has been in review a long time and I want to make the bot stable again. I could just disable the test, but I'd like lld to function properly in general in the meantime too. Co-authored-by: John Holdsworth <[email protected]>
The ASAN bot failed on my previous fix for builds without threading support: https://lab.llvm.org/buildbot/#/builders/24/builds/13751 However that build does have threading enabled, so I do not think my change is the cause. I think the cause is what #157917 will address: > The new PR moves to use madvise() instead of the ad-hoc page referencing code I wrote which should avoid SIGSEGVs if the buffer is deallocated. While that is being reviewed, do not run this test anywhere. Though the failure I saw was with ASAN, I think it could happen anywhere.
Our no threading build appears to be fixed but I got an ASAN failure with that change in a threading build: https://lab.llvm.org/buildbot/#/builders/24/builds/13751 Which "fixed" itself in the next build. So I think this is related to:
And therefore I have left my fixes in and disabled the test everywhere for now. It could be my fault, but I presume you'll start by reverting all my changes anyway in favour of this PR so same result either way. |
Probably seen it before, but just in case: |
Further to #147134 (comment), switch to use the madvise() api to page in mmap'd files and