Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof of concept; client/server architecture with shared cache #23

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ailrst
Copy link
Contributor

@ailrst ailrst commented Dec 18, 2024

When lifting many examples (such as Basil SystemTests) the 2 second evaluation environment initialisation is a significant penalty, this PR aims to avoid this, and allow sharing a cache between invocations. It should produce identical output.

  • Adds a client and server mode, with the previous behaviour still available behind the --local flag. This means there is only one evaluation env that lives in the server. The server only uses Lwt, so there is no parallelism in lifting, but there is enough time saved elsewhere for this to not matter.
  • Uses Lwt_io to do IPC by marshalling messages over Unix domain sockets.
  • Use Jane Street lru_cache to cache disassembled opcodes (this adds annoying dependencies like Core). This cache just lives in memory for the lifetime of the server (or client in the case of local lifting).

gtirb_semantics --serve starts the server listening on a unix domain socket

Initialiesd lifter environment in 2.131941 seconds
Serving on domain socket GTIRB_SEM_SOCKET=/home/[...]/gtirb-semantics/gtirbsock
Decoded 0 instructions  (0 failure) (0.000000 cache hit rate) (0 messages)

E.g. running all the gcc system tests gives a 2x speedup

compile & lift GCC SystemTests gtirb_semantics with env & cache initialized on each client:
make -j10 3145.71s user 457.15s system 991% cpu 6:03.26 total

compile & lift GCC System tests gtirb_sematnics with client-server & shared cache:
make -j10 1457.22s user 316.56s system 983% cpu 3:00.40 total

Server:

Decoded 2312 instructions (0 failure) (0.917396 cache hit rate) (8269 messages)

Note that there were only 2312 cache misses (91% cache hit rate) due to most of these programs being common setup code emitted by gcc.


Lifting cntlm:

client:

$ export GTIRB_SEM_SOCKET=/home/[...]/gtirb-semantics/gtirbsock
$ time dune exec gtirb_semantics -- cntlm-duk.gtirb cntlm-duk.gts                           
Lifted 0 instructions in 56.046047 sec (0.653641 user time) (0 failure) (0.000000 cache hit rate)
dune exec gtirb_semantics -- cntlm-duk.gtirb cntlm-duk.gts  0.52s user 0.23s system 1% cpu 56.152 total

server:

Decoded 51241 instructions  (0 failure) (0.456242 cache hit rate) (22430 messages)

We can see the client spends all its time asleep waiting for the socket (0.6s of work out of the 58s of elapsed time).
When executing locally we have a similar amount of time, since for large programs the initialisation doesn't play as much of a role in comparison to the IPC overhead:

$ time dune exec gtirb_semantics -- --local cntlm-duk.gtirb cntlm-duk.gts                             
Lifted 51242 instructions in 57.652406 sec (57.646956 user time) (0 failure) (0.456232 cache hit rate)
dune exec gtirb_semantics -- --local cntlm-duk.gtirb cntlm-duk.gts  57.50s user 0.25s system 99% cpu 57.772 total

Base automatically changed from unsupported-opcode-fallback to main December 19, 2024 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant