Re: [PATCH] libxfs: use crc32c slice-by-8 variant by default

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, May 14, 2017 at 09:45:45AM +1000, Dave Chinner wrote:
> On Sat, May 13, 2017 at 12:33:44PM -0700, Darrick J. Wong wrote:
> > The crc32c code used in xfsprogs was copied directly from the Linux
> > kernel.  However, that code selects slice-by-4 by default, which isn't
> > the fastest -- that's slice-by-8, which trades table size for speed.
> > Fix some makefile dependency problems and explicitly select the
> > algorithm we want.  With this patch applied, I see about a 10% drop in
> > CPU time running xfs_repair.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> > ---
> >  libxfs/Makefile    |    4 ++--
> >  libxfs/crc32defs.h |    3 +++
> >  2 files changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libxfs/Makefile b/libxfs/Makefile
> > index 0f3759e..c5dc382 100644
> > --- a/libxfs/Makefile
> > +++ b/libxfs/Makefile
> > @@ -124,7 +124,7 @@ LDIRT = gen_crc32table crc32table.h crc32selftest
> >  
> >  default: crc32selftest ltdepend $(LTLIBRARY)
> >  
> > -crc32table.h: gen_crc32table.c
> > +crc32table.h: gen_crc32table.c crc32defs.h
> >  	@echo "    [CC]     gen_crc32table"
> >  	$(Q) $(BUILD_CC) $(BUILD_CFLAGS) -o gen_crc32table $<
> >  	@echo "    [GENERATE] $@"
> > @@ -135,7 +135,7 @@ crc32table.h: gen_crc32table.c
> >  # systems/architectures. Hence we make sure that xfsprogs will never use a
> >  # busted CRC calculation at build time and hence avoid putting bad CRCs down on
> >  # disk.
> > -crc32selftest: gen_crc32table.c crc32table.h crc32.c
> > +crc32selftest: gen_crc32table.c crc32table.h crc32.c crc32defs.h
> >  	@echo "    [TEST]    CRC32"
> >  	$(Q) $(BUILD_CC) $(BUILD_CFLAGS) -D CRC32_SELFTEST=1 crc32.c -o $@
> >  	$(Q) ./$@
> > diff --git a/libxfs/crc32defs.h b/libxfs/crc32defs.h
> > index 64cba2c..153f44c 100644
> > --- a/libxfs/crc32defs.h
> > +++ b/libxfs/crc32defs.h
> > @@ -1,3 +1,6 @@
> > +/* Use slice-by-8, which is the fastest variant. */
> > +# define CRC_LE_BITS 64
> 
> I'm not sure this works on all platforms and builds, whereas the
> existing slice-by-4 default should work for them all

That's why we have a selftest to ensure that the implementation isn't
busted no matter which method we pick.

> but may not be the fastest.
> 
> This code in the crc32defs.h:
> 
> #ifndef CRC_LE_BITS
> #  ifdef CONFIG_64BIT
> #  define CRC_LE_BITS 64
> #  else
> #  define CRC_LE_BITS 32
> #  endif
> #endif
> 
> kinda tells us what the "optimal" default should be.

I know what the code says, I was the person who pushed all that code to
Linus back in 2012 in preparation to add checksums to ext4. :)

That particular hunk is a remnant of the pre-Kconfig method of picking a
variant (and probably should have been ripped out long ago).  Note that the
kernel picks SLICEBY8 by default (I will address the nine exceptions you
pointed out later):

config CRC32_SLICEBY8
	bool "Slice by 8 bytes"
	help
	  Calculate checksum 8 bytes at a time with a clever slicing algorithm.
	  This is the fastest algorithm, but comes with a 8KiB lookup table.
	  Most modern processors have enough cache to hold this table without
	  thrashing the cache.

	  This is the default implementation choice.  Choose this one unless
	  you have a good reason not to.

config CRC32_SLICEBY4
	bool "Slice by 4 bytes"
	help
	  Calculate checksum 4 bytes at a time with a clever slicing algorithm.
	  This is a bit slower than slice by 8, but has a smaller 4KiB lookup
	  table.

	  Only choose this option if you know what you are doing.

config CRC32_SARWATE
	bool "Sarwate's Algorithm (one byte at a time)"
	help
	  Calculate checksum a byte at a time using Sarwate's algorithm.  This
	  is not particularly fast, but has a small 256 byte lookup table.

	  Only choose this option if you know what you are doing.

config CRC32_BIT
	bool "Classic Algorithm (one bit at a time)"
	help
	  Calculate checksum one bit at a time.  This is VERY slow, but has
	  no lookup table.  This is provided as a debugging option.

	  Only choose this option if you are debugging crc32.

Notice how all of the non-SLICEBY8 options tell you to not to choose
that option unless you know what you're doing?  The reason why Kconfig
urges you to pick SLICEBY8 is because people challenged my assertion
that we should use slice by 8 by default, so I wrote a little crc
microbenchmark utility and ran it on as many machines as I could get my
hands on to show that slice by 8 was the fastest.

Every 64-bit machine (and most of the 32-bit ones too) saw the best
results with sb8.  Any machine with more than 4K of cache saw better
results.  The spreadsheet still exists today[1]; note that
'crc32-kern-le' corresponds to the sliceby4 algorithm.

Of course there were questions about "What if my particular board
actually does better with something else?", so after a number of rounds
of bikeshedding we ended up with the Kconfig system that's still there
today.  Hence:

> And keep in mind that the kernel has arch-specific settings:
> 
> $ git grep CONFIG_CRC32_S
> arch/mips/configs/bcm47xx_defconfig:CONFIG_CRC32_SARWATE=y
> arch/mips/configs/db1xxx_defconfig:CONFIG_CRC32_SLICEBY4=y
> arch/mips/configs/rt305x_defconfig:CONFIG_CRC32_SARWATE=y
> arch/mips/configs/xway_defconfig:CONFIG_CRC32_SARWATE=y
> arch/powerpc/configs/adder875_defconfig:CONFIG_CRC32_SLICEBY4=y
> arch/powerpc/configs/ep88xc_defconfig:CONFIG_CRC32_SLICEBY4=y
> arch/powerpc/configs/mpc866_ads_defconfig:CONFIG_CRC32_SLICEBY4=y
> arch/powerpc/configs/mpc885_ads_defconfig:CONFIG_CRC32_SLICEBY4=y
> arch/powerpc/configs/tqm8xx_defconfig:CONFIG_CRC32_SLICEBY4=y
> ....
> 
> Which says that certain mips and powerpc CPUs should be using
> slice-by-4 or sarwate algorithms, not slice-by-8....

All nine of those systems are embedded 32-bit mips/ppc systems with very
small cache sizes which experience cache thrashing with the slice-by-8
algorithm, and therefore chose to pick defaults that are saner for their
particular board configuration.  For nearly all of XFS' perceived
userbase (which I assume are 32 and 64-bit machines with sufficiently
large CPU cache and largeish storage devices) I think slice by 8 is the
right choice.

--D

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@xxxxxxxxxxxxx
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux