Page MenuHomePhabricator

Initiate loading of shared libraries in parallel
Needs RevisionPublic

Authored by scott.smith on Apr 27 2017, 9:59 AM.

Details

Reviewers
zturner
tberghammer
labath
sgraenitz
Group Reviewers
Restricted Project
Summary

This change forks a thread for each shared library, so that as much work as possible can be done in parallel.

Diff Detail

Repository
rL LLVM

Event Timeline

scott.smith created this revision.Apr 27 2017, 9:59 AM
This comment was removed by scott.smith.

update to use a private llvm::ThreadPool. I chose this over a 2nd global "TaskPool" because if the threads are going to be short lived, there isn't much point in having a global pool rather than a short-lived instantiated one.

zturner requested changes to this revision.May 3 2017, 12:28 PM
zturner added a subscriber: zturner.
zturner added inline comments.
source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
537–557

I'm still unclear why we're still going down this route of adding a very specialized instance of parallelism to this one place, that is probably going to be less efficient than having a global thread pool (as now you will have to spin up and destroy the entire thread pool every time you go to load shared libraries).

So, rather than keep repeating the same thing over and over, I went and looked into this a little bit. It turns out LLD has a large library of parallel algorithms in lld/Include/lld/Parallel.h. There is almost nothing specific to LLD in any of these algorithms however, and they should probably be moved to llvm support. Upon doing so, you will be able to write this code as:

std::vector<ModuleSP> Modules(m_rendevous.size());
llvm::parallel_for_each(make_integer_range(0, m_rendevous.size()), [this, &Modules](int I)
  {
    auto &R = m_rendevous[I];
    Modules[I] = LoadModuleAtAddress(R.file_spec, R.link_addr, R.base_addr, true);
  });
for (const auto &M : Modules)
   module_list.Append(M);

Please look into making this change.

This revision now requires changes to proceed.May 3 2017, 12:28 PM
zturner added inline comments.May 3 2017, 12:30 PM
source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
537–557

Note that this is, of course, exactly why I've been saying all along that we should not even be discussing this here. Had the discussion happened over on the LLVM side the first time I asked about this, someone could have mentioned this without me having to spend time looking into it.

scott.smith added inline comments.May 3 2017, 12:39 PM
source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
537–557

As long as those routines allow you to recursively call those routines, then great, go for it.

The spinning up/tearing down of threads is not expensive, at least in my measured use case.

zturner added inline comments.May 3 2017, 12:49 PM
source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
537–557

As long as those routines allow you to recursively call those routines, then great, go for it.

Right, which is why I've asked at least 4 times for it to be looked into. That doesn't mean mean use the first thing you see and check it in right away, it means please see if there is some way to use existing code to solve the problem. If it turns out this doesn't allow recursive use, then a followup would be to understand why not, and if it is hard to change.

So again, please look into this and see if it will work for your needs.

scott.smith added inline comments.
source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
537–557

It seems there are two possible long term fixes:

  1. Separate thread pool
  2. Make parallel_for support recursive use.

Personally I'm in favor of 2. @ruiu brought it up as a preferred goal too. The q is then how to proceed in the short term:

  1. Wait for parallel_for to land in llvm, make it support recursion (hopefully Windows ConcRT supports it too?), then convert this change and commit.
  2. Change TaskMapOverInt to take a ThreadPool, then have it use a private ThreadPool for now, then easily convert to the #1 above later.
  3. Change TaskMapOverInt to support recursion now (which will also require changes to lldb::TaskPool, IMO), then do #1 above once it lands. Advantage is we prove it works, which hopefully makes moving it upstream easier.

Any preferences on how to proceed?

I would suggest adding Pavel and Tamas, or anyone that has contributed to DynamicLoaderPOSIXDYLD as this will affect them.

labath edited edge metadata.May 8 2017, 1:33 PM

I'm out of office this week. Could you hold until I get back? Hopefully we will see some development on the llvm/lld front in the meanwhile.

labath resigned from this revision.Nov 26 2018, 2:54 AM
labath added a subscriber: labath.
sgraenitz resigned from this revision.Sep 24 2019, 6:00 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 24 2019, 6:00 AM