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

buffer more reads from a boot-file file descriptor #769

Merged
merged 1 commit into from
Nov 30, 2023

Conversation

mflatt
Copy link
Contributor

@mflatt mflatt commented Nov 24, 2023

Before:

$ echo "(exit)" | strace -c scheme -q
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 98.87    0.008833           1      4626           read
  0.87    0.000078           1        68           mmap
  0.22    0.000020           2         8           rt_sigaction
  0.03    0.000003           0         6           close
  0.00    0.000000           0         5           mprotect
....

After:

$ echo "(exit)" | strace -c scheme -q
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 68.42    0.001443          51        28           munmap
 24.56    0.000518           3       150           read
  5.17    0.000109           1        68           mmap
  0.95    0.000020           2         8           newfstatat
....

The overall difference in startup time turns out to be very small on Linux and macOS — just a a couple of milliseconds, if anything. But buffering is generally a good idea, and the change makes a startup system-call trace look less suspicious. (See, for example, the discussion in #263.)

I tried this kind of change a couple of times before over the years, but the result always seemed like too much for little benefit. This time, I found a path that involves fewer changes, involves simpler local changes that are easier to check through a diff, and tends to make the code nicer (collapsing two uptr decodings into one) instead of more complicated; so, I think it's worthwhile.

In addition to buffering changes, this commit adds Sregister_boot_file_bytes, so that an embedding application can point to bytes that are already loaded into memory. I experimented with that by linking a program with -sectcreate on macOS and using getsectiondata to find embedded boot files at run time. It doesn't make startup any faster, but that kind of approach might be useful for tools that create a single-file executable including boot files.

@burgerrg
Copy link
Contributor

The Sregister_boot_file_bytes procedure will be useful. I did something similar in the past in Windows to read the boot file from an embedded resource file.

c/scheme.c Outdated Show resolved Hide resolved
c/fasl.c Outdated Show resolved Hide resolved
Without this additional buffering, loading boot files can trigger
thousands of small reads to parse a boot file. Introducing buffering
earlier in the process to reduce the number of those `read` system
calls to between 100 and 200.

The difference in startup time turns out to be very small on Linux and
macOS --- just a a couple of milliseconds, if anything. But buffering
is generally a good idea, and the change makes a startup system-call
trace look less suspicious.

In addition to buffering changes, this commit adds
`Sregister_boot_file_bytes`, so that an embedding application can
point to bytes that are already loaded into memory.
@mflatt mflatt merged commit 0702c8d into cisco:main Nov 30, 2023
13 checks passed
@LiberalArtist
Copy link
Contributor

In addition to buffering changes, this commit adds Sregister_boot_file_bytes, so that an embedding application can point to bytes that are already loaded into memory. I experimented with that by linking a program with -sectcreate on macOS and using getsectiondata to find embedded boot files at run time. It doesn't make startup any faster, but that kind of approach might be useful for tools that create a single-file executable including boot files.

Tangentially, the C23 standard added an #embed preprocessor directive to efficiently and portably embed binary data into programs. It seems like it might be a useful approach to boot files when a sufficiently recent C compiler is available.

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.

4 participants