]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
split: advise the kernel of sequential access pattern
authorPádraig Brady <P@draigBrady.com>
Mon, 8 May 2023 20:22:48 +0000 (21:22 +0100)
committerPádraig Brady <P@draigBrady.com>
Mon, 8 May 2023 20:34:58 +0000 (21:34 +0100)
As split is often dealing with large files,
ensure we indicate to the kernel our sequential access pattern.
This was seen to operate 5% faster when reading from SSD,
as tested with:

dd bs=1M count=2K if=/dev/urandom of=big.in

for split in split.orig split; do
  # Ensure big file is not cached
  dd of=big.in oflag=nocache conv=notrunc,fdatasync count=0 status=none
  # Test read efficiency
  CWD=$PWD; (cd /dev/shm && time $CWD/src/$split -n2 $CWD/big.in)
done

real    0m9.039s
user    0m0.055s
sys     0m3.510s

real    0m8.568s
user    0m0.056s
sys     0m3.752s

* src/split.c (main): Use fdadvise to help the kernel
choose a more appropriate readahead buffer.
* NEWS: Mention the improvement.

NEWS
src/split.c

diff --git a/NEWS b/NEWS
index 9fad8a775dcea87ef4563f2680dcbebfce8b30d4..e07b10e319f107426331552163ae64df2566d27c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,11 @@ GNU coreutils NEWS                                    -*- outline -*-
   due to -i, or -u.  Instead they only output this information with --debug.
   I.e., 'cp -u -v' etc. will have the same verbosity as before coreutils-9.3.
 
+** Improvements
+
+  split now uses more tuned access patterns for its potentially large input.
+  This was seen to improve throughput by 5% when reading from SSD.
+
 
 * Noteworthy changes in release 9.3 (2023-04-18) [stable]
 
index d872ec56a251b71fb347b545e010676d66e040d3..09209cc5a83479d1a9c43e2bd512fa338b7b4c85 100644 (file)
@@ -32,6 +32,7 @@
 #include "alignalloc.h"
 #include "die.h"
 #include "error.h"
+#include "fadvise.h"
 #include "fd-reopen.h"
 #include "fcntl--.h"
 #include "full-write.h"
@@ -1621,6 +1622,9 @@ main (int argc, char **argv)
   /* Binary I/O is safer when byte counts are used.  */
   xset_binary_mode (STDIN_FILENO, O_BINARY);
 
+  /* Advise the kernel of our access pattern.  */
+  fdadvise (STDIN_FILENO, 0, 0, FADVISE_SEQUENTIAL);
+
   /* Get the optimal block size of input device and make a buffer.  */
 
   if (fstat (STDIN_FILENO, &in_stat_buf) != 0)