lfs_bd_cmp() compares more bytes at one time

It's very slowly to compare one byte at one time. Here are the
performance I get from 128M spinand with NFTL by sequential writing.

| file size | buffer size  | write speed  |
| 10 MB     | 0   B        | 3206.01 KB/s |
| 10 MB     | 1   B        | 2434.04 KB/s |
| 10 MB     | 2   B        | 2685.78 KB/s |
| 10 MB     | 4   B        | 2857.94 KB/s |
| 10 MB     | 8   B        | 3060.68 KB/s |
| 10 MB     | 16  B        | 3155.30 KB/s |
| 10 MB     | 64  B        | 3193.68 KB/s |
| 10 MB     | 128 B        | 3230.62 KB/s |
| 10 MB     | 256 B        | 3153.03 KB/s |

| 70 MB     | 0   B        | 2258.87 KB/s |
| 70 MB     | 1   B        | 1827.83 KB/s |
| 70 MB     | 2   B        | 1962.29 KB/s |
| 70 MB     | 4   B        | 2074.01 KB/s |
| 70 MB     | 8   B        | 2147.03 KB/s |
| 70 MB     | 64  B        | 2179.92 KB/s |
| 70 MB     | 256 B        | 2179.96 KB/s |

The 0 Byte size means no validation and the 1 Byte size is how
littlefs do before. Based on the above table and to save memory,
comparing 8 bytes at one time is more wonderful.

Signed-off-by: WeiXiong Liao <liaoweixiong@allwinnertech.com>
This commit is contained in:
WeiXiong Liao
2020-03-13 14:33:12 +08:00
parent ce2c01f098
commit 64f70f51b0

20
lfs.c
View File

@@ -103,18 +103,22 @@ static int lfs_bd_cmp(lfs_t *lfs,
lfs_block_t block, lfs_off_t off, lfs_block_t block, lfs_off_t off,
const void *buffer, lfs_size_t size) { const void *buffer, lfs_size_t size) {
const uint8_t *data = buffer; const uint8_t *data = buffer;
lfs_size_t diff = 0;
for (lfs_off_t i = 0; i < size; i++) { for (lfs_off_t i = 0; i < size; i += diff) {
uint8_t dat; uint8_t dat[8];
int err = lfs_bd_read(lfs,
diff = lfs_min(size-i, sizeof(dat));
int res = lfs_bd_read(lfs,
pcache, rcache, hint-i, pcache, rcache, hint-i,
block, off+i, &dat, 1); block, off+i, &dat, diff);
if (err) { if (res) {
return err; return res;
} }
if (dat != data[i]) { res = memcmp(dat, data + i, diff);
return (dat < data[i]) ? LFS_CMP_LT : LFS_CMP_GT; if (res) {
return res < 0 ? LFS_CMP_LT : LFS_CMP_GT;
} }
} }