Skip to content
This repository has been archived by the owner on May 14, 2019. It is now read-only.

hie executables should be dynamically linked #59

Open
mpickering opened this issue Apr 13, 2019 · 11 comments
Open

hie executables should be dynamically linked #59

mpickering opened this issue Apr 13, 2019 · 11 comments
Assignees

Comments

@mpickering
Copy link

Until very recently nix built haskell packages with --enable-library-for-ghci and --enable-split-sections which causes terrible performance in the runtime linker that ghci uses when compiled in the static manner.

NixOS/nixpkgs#59297

The workaround is to dynamically link the executable and then the system dynamic linker is used instead of the one built into GHC. The difference between the two is significant (2 mins vs 0.3s).

https://gitlab.haskell.org/ghc/ghc/issues/15524

It would seem prudent to build the hie in this manner in hie-nix as users might also run into this problem using an older nixpkgs commit.

@domenkozar
Copy link
Owner

Thanks for the report!

Linking hie-nix dynamically takes a lot of space (there are 3 GHCs with 200 packages in the closure). I will bump nixpkgs (as far as I understand the fix in nixpkgs addresses the issue for static linking) and advise everyone to upgrade.

@mpickering
Copy link
Author

Bumping the nixpkgs which you use to build HIE won't fix the issue. It is the tooling users who need to bump the version of nixpkgs they use.

@domenkozar
Copy link
Owner

So only those that use hie with Nix built projects would be affected?

@mpickering
Copy link
Author

The runtime linker built into GHC performs worse than the system linker. When you statically link the executable then GHC API programs use the built-in rather than system linker.

There are some things you can do to make the runtime linker perform very badly.

  1. Enabling --split-sections
  2. Enabling --build-library-for-ghci

Enabling both of these together causes some non-linear behavior to be exhibited which means loading packages such as jsaddle-dom take a very very long time.

So in theory anyone can be affected but because the only packaging I know of which enabled these two options together was nixpkgs then it is realistically only people who use nix to manage haskell dependencies who are affected.

@domenkozar
Copy link
Owner

domenkozar commented Apr 15, 2019

AFAIK split sections are enabled by default on Linux at least, so it's really about (2).

I'm not sure if 100% of hie-nix users should suffer to download a huge closure or a few % of hie-nix users that use Nix should be notified somehow to upgrade.

@mpickering
Copy link
Author

Surely every person who uses hie-nix uses nix?

@domenkozar
Copy link
Owner

I don't, but I see your point. Let me see how big is the closure with dynamic linking.

@domenkozar
Copy link
Owner

Closure size goes from 6.6GB to 13GB.

@infinisil
Copy link
Contributor

Hey I just made https://github.com/infinisil/all-hies which includes builds for all GHC versions. @domenkozar notified me regarding this issue, but I'm still a bit confused.

Do I understand it right that:

  • Statically built Haskell executables (like hie-nix or all-hies) have very bad runtime performance (you mentioned for linking, but HIE afaik doens't do any linking?)
  • This can be fixed by the end user upgrading their nixpkgs version used for their haskell projects (but what has this to do with HIE?)
  • or this can be fixed by dynamically linking HIE (but what has this to do with he users project?)

I'd really like some concrete answers to that.

@mpickering
Copy link
Author

  1. Statically linked executables which use the GHC API have poor performance when loading .so files which is required when TemplateHaskell is enabled. The problem is much worse if you turn on --split-sections and even worse when you turn on --enable-library-for-ghci.

see: https://gitlab.haskell.org/ghc/ghc/issues/15524

  1. If a user upgrades their nixpkgs then nix will only enable --split-sections and not --enable-library-for-ghci so the load times will be much faster but still slower than dynamic linking.
  2. The only workaround to mitigate the packaging decision by nix is to dynamically link the hie executable.

@infinisil
Copy link
Contributor

Ahh! Thanks a lot, that cleared everything up, especially the Haskell API part. I actually had problems with loading times of TH projects when I started using HIE (5 minutes to start..), so I avoided TH until now. If dynamic linking solves this problem then that's a very good motivator to start using it.

infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
infinisil added a commit to infinisil/all-hies that referenced this issue Apr 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants