Boost.AFIO    Boost C++ Libraries
Public Types | Public Member Functions
boost::afio::utils::secded_ecc< blocksize > Class Template Reference

Calculates the single error correcting double error detecting (SECDED) Hamming Error Correcting Code for a blocksize block of bytes. For example, a secdec_ecc<8> would be the very common 72,64 Hamming code used in ECC RAM, or secdec_ecc<4096> would be for a 32784,32768 Hamming code. More...

List of all members.

Public Types

enum  verify_status { corrupt = 0, okay = 1, healed = 2 }
 The outcomes from verify() More...
typedef unsigned int result_type
 The largest ECC which can be calculated.

Public Member Functions

constexpr secded_ecc ()
 Constructs an instance, configuring the necessary lookup tables.
constexpr result_type result_bits_valid () const noexcept
 The number of bits valid in result_type.
result_type operator() (result_type ecc, const char *buffer) const noexcept
 Accumulate ECC from fixed size buffer.
result_type operator() (const char *buffer) const noexcept
result_type operator() (result_type ecc, const char *buffer, size_t length) const noexcept
 Accumulate ECC from partial buffer where length <= blocksize.
result_type operator() (const char *buffer, size_t length) const noexcept
result_type find_bad_bit (result_type good_ecc, result_type bad_ecc) const noexcept
 Given the original ECC and the new ECC for a buffer, find the bad bit. Return (result_type)-1 if not found (e.g. ECC corrupt)
verify_status verify (char *buffer, result_type good_ecc) const noexcept
 Verifies and heals when possible a buffer, returning non zero if the buffer is error free.

Detailed Description

template<size_t blocksize>
class boost::afio::utils::secded_ecc< blocksize >

Calculates the single error correcting double error detecting (SECDED) Hamming Error Correcting Code for a blocksize block of bytes. For example, a secdec_ecc<8> would be the very common 72,64 Hamming code used in ECC RAM, or secdec_ecc<4096> would be for a 32784,32768 Hamming code.

Did you know that some non-ECC RAM systems can see 1e-12 flips/bit/hour, which is 3.3 bits flipped in a 16Gb RAM system per 24 hours). See Schroeder, Pinheiro and Weber (2009) 'DRAM Errors in the Wild: A Large-Scale Field Study'.

After construction during which lookup tables are built, no state is modified and therefore this class is safe for static storage (indeed if C++ 14 is available, the constructor is constexpr). The maximum number of bits in a code is a good four billion, I did try limiting it to 65536 for performance but it wasn't worth it, and one might want > 8Kb blocks maybe. As with all SECDED ECC, undefined behaviour occurs when more than two bits of error are present or the ECC supplied is incorrect. You should combine this SECDED with a robust hash which can tell you definitively if a buffer is error free or not rather than relying on this to correctly do so.

The main intended use case for this routine is calculating the ECC on data being written to disc, and hence that is where performance has been maximised. It is not expected that this routine will be frequently called on data being read from disc i.e. only when its hash doesn't match its contents which should be very rare, and then a single bit heal using this routine is attempted before trying again with the hash. Care was taken that really enormous SECDEDs are fast, in fact tuning was mostly done for the 32784,32768 code which can heal one bad bit per 4Kb page as the main thing we have in mind is achieving reliable filing system code on computers without ECC RAM and in which sustained large quantities of random disc i/o produce a worrying number of flipped bits in a 24 hour period (anywhere between 0 and 3 on my hardware here, average is about 0.8).

Performance of the fixed block size routine where you supply whole chunks of blocksize is therefore particularly excellent as I spent a lot of time tuning it for Ivy Bridge and later out of order architectures: an amazing 22 cycles per byte for the 32784,32768 code, which is a testament to modern out of order CPUs (remember SECDED inherently must work a bit at a time, so that's just 2.75 amortised CPU cycles per bit which includes a table load, a bit test, and a conditional XOR) i.e. it's pushing about 1.5 ops per clock cycle. On my 3.9Ghz i7-3770K here, I see about 170Mb/sec per CPU core.

The variable length routine is necessarily much slower as it must work in single bytes, and achieves 72 cycles per byte, or 9 cycles per bit (64Mb/sec per CPU core).

{O(N) where N is the blocksize} {Throws constexpr exceptions in constructor only, otherwise entirely noexcept.}

Definition at line 5968 of file afio.hpp.


Member Typedef Documentation

template<size_t blocksize>
typedef unsigned int boost::afio::utils::secded_ecc< blocksize >::result_type

The largest ECC which can be calculated.

Definition at line 5971 of file afio.hpp.


Member Enumeration Documentation

template<size_t blocksize>
enum boost::afio::utils::secded_ecc::verify_status

The outcomes from verify()

Enumerator:
corrupt 

The buffer had more than a single bit corrupted or the ECC was invalid.

okay 

The buffer had no errors.

healed 

The buffer was healed.

Definition at line 6162 of file afio.hpp.


Constructor & Destructor Documentation

template<size_t blocksize>
constexpr boost::afio::utils::secded_ecc< blocksize >::secded_ecc ( )

Constructs an instance, configuring the necessary lookup tables.

Definition at line 6020 of file afio.hpp.


Member Function Documentation

template<size_t blocksize>
constexpr result_type boost::afio::utils::secded_ecc< blocksize >::result_bits_valid ( ) const

The number of bits valid in result_type.

Definition at line 6061 of file afio.hpp.

template<size_t blocksize>
result_type boost::afio::utils::secded_ecc< blocksize >::operator() ( result_type  ecc,
const char *  buffer 
) const

Accumulate ECC from fixed size buffer.

Definition at line 6066 of file afio.hpp.

template<size_t blocksize>
result_type boost::afio::utils::secded_ecc< blocksize >::operator() ( result_type  ecc,
const char *  buffer,
size_t  length 
) const

Accumulate ECC from partial buffer where length <= blocksize.

Definition at line 6117 of file afio.hpp.

template<size_t blocksize>
result_type boost::afio::utils::secded_ecc< blocksize >::find_bad_bit ( result_type  good_ecc,
result_type  bad_ecc 
) const

Given the original ECC and the new ECC for a buffer, find the bad bit. Return (result_type)-1 if not found (e.g. ECC corrupt)

Definition at line 6146 of file afio.hpp.

template<size_t blocksize>
verify_status boost::afio::utils::secded_ecc< blocksize >::verify ( char *  buffer,
result_type  good_ecc 
) const

Verifies and heals when possible a buffer, returning non zero if the buffer is error free.

Definition at line 6169 of file afio.hpp.


January, 2014

Copyright © 2013-2014 Niall Douglas, Cork, Ireland
Copyright © 2013 Paul Kirth, California
Documentation is generated by Doxygen