打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Implementing concurrent linking in GNU Gold linker

Introduction to concurrent linking

Generally, linking is the last phase in the build process of C/C++ programs. Most build systems, for example GNU Make, invoke programs defined in the build system, when a given set of prerequisites is completed. That way, linking requires that all linker input files (object files, shared objects, archives, etc.) are built, before linking can start.

While source compilation can mostly be parallelized well, the linking jobs cause CPU underutilization, because it has to wait for all its input files to finish. The result is that the linking phase will add a significant amount of time to the build process, when a program is rebuilt (the edit-compile-run cycle).

This blog post will introduce a technique, called concurrent linking, which makes it possible to start the linking phase during the compilation process. Note that concurrent linking is different from parallel linking, since the latter will speed up the linking process by using multiple threads, while the former technique will speed up the overall build process by reducing core underutilization and thus improving overall parallelism.

Reasons to choose the GNU Gold linker

GNU Gold 1 is a relative new ELF linker and written from scratch in C++ by Ian Lance Taylor 2. Given the fact that GNU Gold is written from scratch, and designed to speed up the linking process with multiple threads, it is a great candidate to implement concurrent linking.

In the past, I've done build system analysis 3 for Mozilla's JavaScript engine Spidermonkey (see previous blog posts) and one of the conclusions is that linking libmozjs, followed by the JavaScript shell itself, is the most time consuming part of rebuilding the shell. For my bachelor thesis, I'm implementing concurrent linking in GNU Gold, in order to demonstrate the positive impact of using concurrent linking while rebuilding C/C++ programs.

Once concurrent linking is implemented in GNU Gold, it will speed up the overall (re)build process compared to GNU ld, since it also features incremental linking and parallel linking. The older GNU ld does not support these features (and it probably will never support them). The disadvantage of Gold is that it only targets ELF, while GNU ld support various executable and linking formats.

Implementing concurrent linking in Gold

When GNU Make has constructed its directed acyclic graph of targets and prerequisites, it knows almost all recipes to invoke. My solution is that GNU Make should do a similar trick as it does with recursive Make instances: GNU Make's jobserver creates a pipe to each recursive Make instance and passes on tokens, in order to divide the available job slots to the child Make processes. 4

For concurrent linking, if Make sees that linking using Gold is necessary for a target and the --concurrent-linking flag is set for Gold, Make starts Gold when the first object file is ready. Make will create a pipe and sends each filename to Gold through the pipe.

Reading from the pipe (Gold's side) will block until:

  1. there is no more data to read from the pipe. Filenames are separated using a \0 char (since \n is considered valid as a character for filenames).
  2. all objects are sent through the pipe (e.g. close() from Make).

In the first case, Gold can produce parts of the final output file, with the input files sent thus far. In the second case, Gold can safely finish the output file (since all files are received through the pipe).

Backwards compatibility

In order to maintain backwards compatibility with older Makefiles and GNU Make, GNU Make should set an environment variable (e.g. GOLD_CONCURRENT_LINKING or something shorter). If developers want concurrent linking, the Makefile can set --concurrent-linking, if the Makefile sees that GOLD_CONCURRENT_LINKING is defined, otherwise it will do nothing. For example:

ifdef USE_GOLD_LINKER  ifdef GOLD_CONCURRENT_LINKING  LDFLAGS += --concurrent-linking  endif  endif  

Using this approach, build systems can reduce their build times, by improving their parallelism and thus reducing CPU core underutilization.

Missing puzzle pieces

There are still some missing pieces:

  1. How to detect if Gold is used as linker? This can be solved using a configure script, which will set USE_GOLD_LINKER when the testcase which detects the use of GNU Gold succeeds.
  2. Gold supports linking with multiple threads, but how many threads should be used for linking? This depends on the available job slots and compilation-linking ratio 5 and compiler optimization flags.
  3. Can GNU Make use the job slot of a suspended Gold linker? If the Gold linker is blocked (waiting for filenames from the pipe), the job slot is in use for a suspended task. If GNU Make can temporarely use the token for another job, the amount of concurrently running jobs can be optimal.

Experiments will tell what's useful and what's slowing things down. Those experiments are done after implementing concurrent linking in GNU Gold, since these uncertainties are more related to tweaking Makefiles and GNU Make.

Footnotes and further reading

  1. GNU Gold is part of GNU Binutils 2.21: http://sourceware.org/binutils/. Note that Gentoo's GNU Binutils version \< 2.21 does not build the Gold linker, however GNU Gold is added to Binutils 2.18 in 2008. http://cygwin.com/ml/binutils/2008-03/msg00162.html ?

  2. Ian Lance Taylor is currently a Google employee, the main author of GNU Gold and has a detailed blog about linkers and loaders. http://www.airs.com/blog/ ?

  3. BSA is a build system analysis tool for GNU Make and PyMake. BSA is mostly a viewer used for analysis and a set of script to generate content for the viewer. The viewer enables a developer to see exactly which part of the build system is time consuming and which part should be altered to improve parallelism. http://smvv.kompiler.org/bsa/ ?

  4. GNU Make's jobserver implementation is descripted in detail at http://mad-scientist.net/make/jobserver.html ?

  5. Compilation-linking ratio is the number of concurrent compilation jobs that will provide sufficient object files in time that a single linker instance can do its work without stalling. ?

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
[LLVMdev] Proposal: MCLinker
How can I link a static library to a dynamic library?
程序编译链接运行时对库关系的探讨
top加强版htop安装
GNU 編譯器組合(MSP430)
lfs简要解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服