Extended lfsr_data_t to support 1 and 2 leb128 encodings

The idea of this is:

1. Aside from the encoded size, our lfsr_data_t has space for 2 integers.
2. Our mdir addresses are exactly 2 leb128s.
3. We already need to be able to inject 1 leb128 for did entries.

So if we can cram our 2 leb128s inline into the lfsr_data_t, we should
be able to avoid the indirection, wasted space in lfsr_data_t, and
duplicate encoding costs for the mdir addresses.

Conveniently for us, there are exactly 2 unused bits in various fields,
thanks to our common 31-bit limits.

It's a bit awkward since we must assume our buffer pointer uses all
32-bits, but here are the current encodings:

  00 = in-device buffer    10 = on-disk data
       no leb128s               no leb128s
  .----+----+----+----.  .----+----+----+----.
  |0|      size       |  |1|      size       |
  |----+----+----+----|  |----+----+----+----|
  |0000000000000000000|  |0|     offset      |
  |----+----+----+----|  |----+----+----+----|
  |       buffer      |  |       block       |
  '----+----+----+----'  '----+----+----+----'

  01 = in-device buffer      11 = 2 leb128s
       1 leb128
  .----+----+----+----.  .----+----+----+----.
  |0|      size       |  |1|      size       |
  |----+----+----+----|  |----+----+----+----|
  |1|     leb128      |  |1|     leb128      |
  |----+----+----+----|  |----+----+----+----|
  |       buffer      |  |       leb128      |
  '----+----+----+----'  '----+----+----+----'

This encoding also presents a relatively nice code-path, since we can
treat the 2 leb128 case as an on-disk data reference with no size.

Unfortunately the initial measurements look, uh, really bad:

            code          stack
  before:  22194           2048
  after:   22426 (+1.0%)   2088 (+2.0%)

This needs more investigation, but from what I can tell so far the RAM
cost comes from the leb128 encoding buffer moving into the "hot path",
aka the deepest call stack in littlefs, which involves lfsr_data_read
as a part of mtree traversal as a part of block allocation.

I have no idea about the code cost though...
This commit is contained in:
Christopher Haster
2023-08-08 15:38:05 -05:00
parent 78a199b59b
commit cc991396c2
2 changed files with 129 additions and 89 deletions
+5
View File
@@ -334,6 +334,11 @@ ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size);
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size);
static inline size_t lfs_sizeleb128(uint32_t word) {
// this is the size of the leb128 after encoding
return (lfs_nlog2(word+1)+7-1) / 7;
}
// Calculate CRC-32 with polynomial = 0x04c11db7