Anticipatory shader cache loading #89

Closed
roothorick opened this Issue Feb 18, 2018 · 15 comments

Comments

Projects
None yet
8 participants

It would dramatically reduce stutters on subsequent launches in some games if dxvk keeps track of shaders and pipelines that were used on previous runs, and recreates them on the side before the application requests them. This way they're ready when the app needs them, avoiding hitches that could potentially be lengthy if the app suddenly needs many and/or large shaders.

The obvious approach is flat files stored somewhere (probably yet another environment variable for now) with the executable's full path and a table of remembered pipelines and shaders. Upon device creation, dxvk would check for a file corresponding to the executable path, and if found, recreate the listed pipelines from shader files stored on disk, preferably in one or more dedicated worker threads.

This comment has been minimized.

Show comment Hide comment
@doitsujin

doitsujin Feb 18, 2018

Owner

The Vulkan pipeline cache should already handle this well enough, the only thing left to do is to actually store it somewhere (an obvious place would be $HOME/.cache on Linux). I think RADV already stores its own shader cache files somewhere already.

Owner

doitsujin commented Feb 18, 2018

The Vulkan pipeline cache should already handle this well enough, the only thing left to do is to actually store it somewhere (an obvious place would be $HOME/.cache on Linux). I think RADV already stores its own shader cache files somewhere already.

This comment has been minimized.

Show comment Hide comment
@SveSop

SveSop Feb 18, 2018

Well.. not sure how things tie together, but with nVidia, there is a .nv folder that stores cache... and several games also have their own "cache".. So adding 1 more.. Dunno.

The nVidia implementation of shader cache already causes loads of stuttering when being created, but it is somewhat related to a low amount of storage (dont remember the numbers atm.. But running 4-5 games will cause the shaders to go out of space and be recreated, causing loads of stutters).

Can be worked around by giving each game their own cache, so that should be opted for if its implemented in DXVK i guess. Env. variable or some sort of separation of it to be sure its not overwritten or otherwise "run out of space" :)

SveSop commented Feb 18, 2018

Well.. not sure how things tie together, but with nVidia, there is a .nv folder that stores cache... and several games also have their own "cache".. So adding 1 more.. Dunno.

The nVidia implementation of shader cache already causes loads of stuttering when being created, but it is somewhat related to a low amount of storage (dont remember the numbers atm.. But running 4-5 games will cause the shaders to go out of space and be recreated, causing loads of stutters).

Can be worked around by giving each game their own cache, so that should be opted for if its implemented in DXVK i guess. Env. variable or some sort of separation of it to be sure its not overwritten or otherwise "run out of space" :)

This comment has been minimized.

Show comment Hide comment
@pchome

pchome Feb 18, 2018

Contributor

an obvious place would be $HOME/.cache on Linux

Actually $XDG_CACHE_HOME
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

User may want (or already did) to redefine it. A very common practice to set it as /tmp/.cache for example which (/tmp) will (should) be cleared after reboot. Also /tmp is usually tmpfs - fast in-memory temporary filesystem.

Contributor

pchome commented Feb 18, 2018

an obvious place would be $HOME/.cache on Linux

Actually $XDG_CACHE_HOME
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

User may want (or already did) to redefine it. A very common practice to set it as /tmp/.cache for example which (/tmp) will (should) be cleared after reboot. Also /tmp is usually tmpfs - fast in-memory temporary filesystem.

This comment has been minimized.

Show comment Hide comment
@SveSop

SveSop Feb 18, 2018

User may want (or already did) to redefine it. A very common practice to set it as /tmp/.cache for example which (/tmp) will (should) be cleared after reboot. Also /tmp is usually tmpfs - fast in-memory temporary filesystem.

Well.. tbh using tmpfs defeats the purpose of having a cache "for-later-use". The point i THINK @roothorick was trying to achieve with this cache is to not have the driver recompile the shaders each time, and saving shaders to volatile memory would only be valid for that session of computer use. Unless ofc the computer is powered on 24/7...

SveSop commented Feb 18, 2018

User may want (or already did) to redefine it. A very common practice to set it as /tmp/.cache for example which (/tmp) will (should) be cleared after reboot. Also /tmp is usually tmpfs - fast in-memory temporary filesystem.

Well.. tbh using tmpfs defeats the purpose of having a cache "for-later-use". The point i THINK @roothorick was trying to achieve with this cache is to not have the driver recompile the shaders each time, and saving shaders to volatile memory would only be valid for that session of computer use. Unless ofc the computer is powered on 24/7...

This comment has been minimized.

Show comment Hide comment
@roothorick

roothorick Feb 18, 2018

The original idea was to prevent a game that compiles pipelines during gameplay from waiting on the pipeline to become available (resulting in a hitch) by having that pipeline already ready to go.

roothorick commented Feb 18, 2018

The original idea was to prevent a game that compiles pipelines during gameplay from waiting on the pipeline to become available (resulting in a hitch) by having that pipeline already ready to go.

This comment has been minimized.

Show comment Hide comment
@pchome

pchome Feb 19, 2018

Contributor

This shaders are not too big so why not to store them in memory? For a while at least.

Both *.dxbc and *.spv generated after Superposition test ~6 Mb and optimized ones ~4 Mb.
TW3's - 25 and 15 after spending some time in game.

So I think about some kind of in-memory-database where all this shaders can be stored and accessed by id (VS_ce8f5bfde13924bc08ecbbb615a50f7b72dce93e.spv or <expected_result_id> for example). Then this DB can be copied/updated to an physical storage and loaded back into memory when application/game launching. This will help with i/o and compilation overhead.

Contributor

pchome commented Feb 19, 2018

This shaders are not too big so why not to store them in memory? For a while at least.

Both *.dxbc and *.spv generated after Superposition test ~6 Mb and optimized ones ~4 Mb.
TW3's - 25 and 15 after spending some time in game.

So I think about some kind of in-memory-database where all this shaders can be stored and accessed by id (VS_ce8f5bfde13924bc08ecbbb615a50f7b72dce93e.spv or <expected_result_id> for example). Then this DB can be copied/updated to an physical storage and loaded back into memory when application/game launching. This will help with i/o and compilation overhead.

This comment has been minimized.

Show comment Hide comment
@doitsujin

doitsujin Feb 19, 2018

Owner

@pchome Applications generally perform the DXBC->SPIR-V translation only once for each shader, and usually when loading the game, so I don't see what that is supposed to help with. What @roothorick is referrig to is the stutter when Vulkan pipelines are created, which happens during rendering.

Owner

doitsujin commented Feb 19, 2018

@pchome Applications generally perform the DXBC->SPIR-V translation only once for each shader, and usually when loading the game, so I don't see what that is supposed to help with. What @roothorick is referrig to is the stutter when Vulkan pipelines are created, which happens during rendering.

This comment has been minimized.

Show comment Hide comment
@pchome

pchome Feb 19, 2018

Contributor

Applications generally perform the DXBC->SPIR-V translation only once for each shader

Sorry for bothering you with stupid questions/suggestions. But what about this debug: Compiling shader VS_... duplicates in log? I know nothing about shaders and how do they handled by dxvk and can suppose they been compiled with different parameters or so.

Here is some numbers #75 (comment)

For superposition :

     61 debug: Compiling shader VS_50dbfbd6521351958857579f020ac5470069ec8d
     32 debug: Compiling shader VS_a7280f2bf16459e952052dbc90c766657567dc37
     26 debug: Compiling shader VS_8b0d83969656d6bcfbd7b807009b297b5445542f
     23 debug: Compiling shader VS_c823713c5f7f2c28be2dda84cd3e2bf2799d49df
     15 debug: Compiling shader PS_9b7240e282984a82c41b2ccfde704b6acb60f283
     11 debug: Compiling shader VS_64546c77b9dd9a8727b2564851fa2874c8c6baef
     10 debug: Compiling shader PS_776858535c6ed5c29a428b6369be9cf9a992ac46
Contributor

pchome commented Feb 19, 2018

Applications generally perform the DXBC->SPIR-V translation only once for each shader

Sorry for bothering you with stupid questions/suggestions. But what about this debug: Compiling shader VS_... duplicates in log? I know nothing about shaders and how do they handled by dxvk and can suppose they been compiled with different parameters or so.

Here is some numbers #75 (comment)

For superposition :

     61 debug: Compiling shader VS_50dbfbd6521351958857579f020ac5470069ec8d
     32 debug: Compiling shader VS_a7280f2bf16459e952052dbc90c766657567dc37
     26 debug: Compiling shader VS_8b0d83969656d6bcfbd7b807009b297b5445542f
     23 debug: Compiling shader VS_c823713c5f7f2c28be2dda84cd3e2bf2799d49df
     15 debug: Compiling shader PS_9b7240e282984a82c41b2ccfde704b6acb60f283
     11 debug: Compiling shader VS_64546c77b9dd9a8727b2564851fa2874c8c6baef
     10 debug: Compiling shader PS_776858535c6ed5c29a428b6369be9cf9a992ac46

This comment has been minimized.

Show comment Hide comment
@SveSop

SveSop Feb 19, 2018

But what about this debug: Compiling shader VS_... duplicates in log?

What do you mean by "duplicates". Those lines you pasted there are not duplicates.
VS_50dbfbd6521351958857579f020ac5470069ec8d is one shader, VS_c823713c5f7f2c28be2dda84cd3e2bf2799d49df is another one. A app/game/whatever will usually generate loads of them, and they are all "unique".

Sorry if i missunderstand your question tho :)

SveSop commented Feb 19, 2018

But what about this debug: Compiling shader VS_... duplicates in log?

What do you mean by "duplicates". Those lines you pasted there are not duplicates.
VS_50dbfbd6521351958857579f020ac5470069ec8d is one shader, VS_c823713c5f7f2c28be2dda84cd3e2bf2799d49df is another one. A app/game/whatever will usually generate loads of them, and they are all "unique".

Sorry if i missunderstand your question tho :)

This comment has been minimized.

Show comment Hide comment
@pchome

pchome Feb 19, 2018

Contributor

What do you mean by "duplicates".

61 times this string appeared in log file.

Command ussed:
$ grep "Compiling shader" dxvk_d3d11.log | sort | uniq -c | sort -nr -k1

Contributor

pchome commented Feb 19, 2018

What do you mean by "duplicates".

61 times this string appeared in log file.

Command ussed:
$ grep "Compiling shader" dxvk_d3d11.log | sort | uniq -c | sort -nr -k1

This comment has been minimized.

Show comment Hide comment
@volca02

volca02 Feb 19, 2018

Isn't this stuff dependent on settings, though? I mean changing graphical settings would likely change a lot of the stuff in the pipelines?

volca02 commented Feb 19, 2018

Isn't this stuff dependent on settings, though? I mean changing graphical settings would likely change a lot of the stuff in the pipelines?

This comment has been minimized.

Show comment Hide comment
@Guy1524

Guy1524 Feb 20, 2018

Contributor

@volca02 Yes, but that is not relevant, if you were to change settings, the pipelines would be generated and stored for later use.

Contributor

Guy1524 commented Feb 20, 2018

@volca02 Yes, but that is not relevant, if you were to change settings, the pipelines would be generated and stored for later use.

This comment has been minimized.

Show comment Hide comment
@jmis

jmis Mar 18, 2018

Path of Exile appears to compile shaders on the fly which makes the game unplayable until a cache is built up. Given the number of shaders required, it's not a good experience. The Wine DX9 to OpenGL translation layer allowed the "UseGLSL" option to disable the compilation.

jmis commented Mar 18, 2018

Path of Exile appears to compile shaders on the fly which makes the game unplayable until a cache is built up. Given the number of shaders required, it's not a good experience. The Wine DX9 to OpenGL translation layer allowed the "UseGLSL" option to disable the compilation.

This comment has been minimized.

Show comment Hide comment
@dumpsters

dumpsters Mar 20, 2018

It's true, just a couple minutes of playing with DXVK_SHADER_DUMP_PATH on and there are over 2k files in the directory. One thing I'm curious about is if games that store their own shader cache have problems with DXVK or AMD drivers? for instance with PoE you have two shader cache folders in the game dir + AMD shader cache on windows, does that degrade DXVK performance in any way?

It's true, just a couple minutes of playing with DXVK_SHADER_DUMP_PATH on and there are over 2k files in the directory. One thing I'm curious about is if games that store their own shader cache have problems with DXVK or AMD drivers? for instance with PoE you have two shader cache folders in the game dir + AMD shader cache on windows, does that degrade DXVK performance in any way?

This comment has been minimized.

Show comment Hide comment
@doitsujin

doitsujin Mar 21, 2018

Owner

Commit 4518b1b stores the Vulkan pipeline to disk, which should reduce the stutter in subsequent runs of any application, at least on drivers that do not do this automatically already (such as RADV).

Owner

doitsujin commented Mar 21, 2018

Commit 4518b1b stores the Vulkan pipeline to disk, which should reduce the stutter in subsequent runs of any application, at least on drivers that do not do this automatically already (such as RADV).

@doitsujin doitsujin closed this Mar 21, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment