protonscr

Optimization: Symbol visibility

dxvkclosed
doitsujin/dxvk#1051 · opened 2019-05-12 by pchome · updated 2019-05-14 · 4 comments · github
Ppchome 2019-05-12 github

https://gcc.gnu.org/wiki/Visibility

TL;DR: Can greatly reduce resulting binary size.

I'm not sure about MinGW build, but it was proven (in combination with -fwhole-program GCC flag) winelib binaries was smaller up to ~40% (https://github.com/doitsujin/dxvk/issues/646#issuecomment-424178821):

lib system test no custom opt (--buildtype "release")
dxgi.dll.so 931592 632680 620296
d3d11.dll.so 1728584 1118024 1076968
system  - system-wide compiler flags + meson unity
test    - system-wide compiler flags + meson unity +  `-fwhole-program`
default - no custom compiler flags, no meson unity

MinGW (https://github.com/doitsujin/dxvk/issues/646#issuecomment-425500741):

lib default unity -fwhole-program
dxgi.dll.so 1600512 2128384 1406464
d3d11.dll.so 2014208 2807296 1666048

All provided data is old, for version ~0.80.

So even w/o -fwhole-program we should expect great improvement for tuned visibility. Also it should require slightly more changes.

It was too early for different tunings/optimizations a while ago, but maybe now it's time?

If you don't mind such changes, then it could be started as simple visibility definition for winelib. Then series of commits, until DXVK will compile with -fvisibility=hidden GCC flag (see "Step-by-step guide" part).

p.s. mentioned in guide -fvisibility-inlines-hidden flag reduces size for several KB w/o any changes in codebase.

Ppchome 2019-05-12 github

BTW, for -fwhole-program hack I used externally_visible attribute in place of default visibility (or additional used attribute). Common-Function-Attributes

This attribute, attached to a global variable or function, nullifies the effect of the -fwhole-program command-line option, so the object remains visible outside the current compilation unit.

Hack for dxvk-1.1, just for reference: dxvk-1.1-whole-program-support.patch.txt.
EDIT: probably patch from https://github.com/doitsujin/dxvk/pull/604#issuecomment-416283000 should be applied too for this to work.

FYI.

Ddoitsujin maintainer 2019-05-12 github

I'd like to ask you to actually provide a clear and simple description of what you want to do, why, and how your patch/PR/whatever actually addresses that. I know you always write a large amount of text, but it's always so incredibly confusing that I have no idea what this is all about and would rather not bother with it.

In other words, why do we need a 500+ line patch of which I have no idea what they are doing to save a few kilobytes that pretty much nobody cares about? Is this really worth the risk of introducing regressions?

Ppchome 2019-05-12 github

Sorry, my English is horrible.

I'll try to explain as best as I can.

What is this?

There is a lot of symbols included in generated binary (for C++ program). Check using F3->F8(filtered view) in mc or nm -C -D <library>.so. Most of them can be "skipped" by marking them as local(hidden), or external(default/visible). This allow compiler to:

  • generate more compact DSO, which greatly reducing size
  • use more aggressive optimizations, or even drop unused code, which is good for performance

For more details (and correct description) see provided link to GCC Wiki (and How To Write Shared Libraries referenced there, if you want even more technical details).

Why?

Well, ...

  • I'm using winelib on Gentoo, had a lot of patches, now dropped them entirely from my DXVK overlay and trying to provide an ebuild suitable to be included into official Gentoo portage...

    Hello, Gentoo users! If anyone feel brave enough to maintain such ebuild -- feel free to grab one from mentioned overlay and PR to https://github.com/gentoo/gentoo. I personally still thinking about add or remove some functionality.

  • But I missing my patches, so trying to propose some non-destructive changes to DXVK upstream. So minimal changes then will be required for me to use hardcore patch, while still will be able to built as is in Gentto (or in any distro).

  • The patch was added only because it was mentioned, as reference where those numbers was taken from. It shows that -fvisibility=hidden was blindly forced for the whole DXVK code base, and DLLEXPORT was changed to use __attribute__((externally_visible)).

  • Meanwhile, I still want second mentioned patch to be reviewed and accepted upstream. It fixes compilation for some DXVK sample programs (winelib).

TL;DR

I want something like this in DXVK code because I'm lazy ass, don't want to maintain a ton of patches, but want all benefits out of the box. ;)

A good start will be to add #define DLLEXPORT __attribute__((visibility ("default"))) for __WINE__, missing DLLEXPORTs to functions and to test using -fvisibility=hidden GCC flag. This will cost you nothing (and should broke nothing), because default visibility is "default".

Proton

Also, I found there is gcc-8 mentioned in steam runtime jessie branch. So at some point they'll update their runtime and maybe readd DXVK winelib builds to Proton. And then every Proton user will benefit from this.

Added: 3.16-1

  • DXVK is now built as a native Linux library, which may give a small performance boost, and should make debugging easier for DXVK and driver developers.

Removed: 3.16-2

  • DXVK is again built as a Windows DLL, due to incompatibilities with the Steam runtime. This should fix widespread crashes with Direct3D 11 titles.

Well, :joy: The first link in this issue should explain better than all this crap I just wrote.
Ppchome 2019-05-14 github

Closing. #1052 good enough for me. Will file a new issue in case regressions.

Upstream links

DLLs