Files
LibretroAdmin a8b62eba35 retro_cdimage: read images in place, without syscalls per sector
Every sector read was a seek and a read through the VFS, and a CHD
copied each compressed hunk twice on its way to the decoder: from the
file into a 64 KiB request buffer, in pieces of at most 64 KiB, then
into the decoder's own staging buffer.

- Images are opened with RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS,
  and HAVE_MMAP is now defined for unix, osx and Android, so the
  local VFS maps them. A BIN/ISO/CUE sector read becomes a copy out
  of the page cache into the drive's buffer, which is the one copy
  the emulated drive needs.
- CHD: the compressed hunk is lent to the decoder straight from the
  mapping (rchd_feed_borrow), so it is never copied. Unmapped (a
  frontend VFS, a platform without mapping, a file too big to map),
  each hunk is read in one call into a buffer sized to a hunk at open
  and lent from there, rather than copied in again. The open sequence
  is still fed by copy. The file position is tracked so a read that
  continues where the last one stopped does not seek.
- On a mapped CHD the OS is asked to bring the next 1 MiB of the file
  in ahead of the decoder (filestream_prefetch), coalesced so one
  request covers many hunks; cold pages would otherwise stall the
  emulation thread on a page fault.
- BIN/ISO/CUE: a read that starts where the previous one ended skips
  the seek.

Measured over 20 passes of every sector of a 2400-sector test disc:
BIN/CUE went from 75593 read/lseek syscalls to 9 and from 0.57 to
0.22 us per sector; a CHD from 13392 syscalls to 26 (default hunks)
and from 1493 to 28 (1 MiB hunks). Unmapped, lseeks on a CHD dropped
from 6009 to 26 and 1 MiB-hunk reads from 984 to 264.

tools/chd/run.sh now also checks every codec at the largest hunk
chdman writes (1 MiB), and passes under ASan/UBSan on both the mapped
and the unmapped path.
2026-10-28 20:21:11 +01:00
..
2015-08-26 13:46:40 +02:00