Filesystems and block I/O (devb-*) drivers

Here are the basic steps to improving the performance of your filesystems and block I/O (devb-*) drivers.

  1. Optimize disk hardware and driver options. This is most important on non-x86 targets and systems without hard drives (e.g., Microdrive, Compact Flash). Not using the fastest available DMA mode (or degrading to PIO) can easily affect the speed by a factor of ten. For more information, see Connecting Hardware.
  2. Optimize the filesystem options:
    • Determine how you want to balance system robustness and performance (see below).
    • Concentrate on the cache and vnode (filesystem-independent inodes) options; the other sizes scale themselves to these.
    • The default cache is 15% of the total system RAM, to a maximum of 512 MB. This is too large for floppy drivers (devb-fdc) and RAM drivers (devb-ram), but might be too small for intensive use.
    • Set the commit option (either globally or as a mount option) to force or disable synchronous writes.
    • Consider using a RAM disk for temporary files (e.g., /tmp).
  3. Optimize application code:
    • Read and write in large chunks (16–32 KB is optimal).
    • Read and write in multiples of a disk block on block boundaries (typically 512 bytes, but you can use stat() or statvfs() to determine the value at runtime).
    • Avoid standard I/O where possible; use open(), read(), and write(), instead of fopen(), fread(), and fwrite(). The f* functions use an extra layer of buffering. The default size is given by BUFSIZ; you can use setvbuf() to specify a different buffer size.
      Note: As a QNX Neutrino extension, you can use the STDIO_DEFAULT_BUFSIZE environment variable to override BUFSIZ as the default buffer size for stream I/O. The value of STDIO_DEFAULT_BUFSIZE must be greater than that of BUFSIZ.
    • Pregrow files, if you know their ultimate sizes.
    • Use direct I/O (DMA to user space).
    • Use filenames that are no longer than 16 characters. If you do this, the filesystem won't use the .inodes file, so there won't be any inter-block references. In addition, there will be one less disk write, and hence, one less chance of corruption if the power fails.

      Long filenames (i.e., longer than 48 characters) especially slow down the filesystem.

    • Use the -i option to dinit to pregrow the .inodes file, which eliminates the runtime window of manipulating its metadata during a potential power loss.
    • Big directories are slower than small ones, because the filesystem uses a linear search.