greiman/SdFat

Arduino-Pico: huge slowdown with v2.2.2 (vs.2.1.1)

Closed this issue · 5 comments

Hello,
last time I run the "bench" example with Arduino-Pico, I was using v3.3.0 which included v2.1.1 of SdFat.

I got very nice results: 2.42 MB/s read, 2.36 MB/s write.

Now I repeated the test with v3.8.1, which includes SdFat v2.2.2

Results are much worse (same freshly formatted microSD, same clock, same SPI speed):

Use a freshly formatted SD for best performance.

Type any character to start
FreeStack: 192400
Type is FAT32
Card size: 31.91 GB (GB = 1E9 bytes)

Manufacturer ID: 0X3
OEM ID: SD
Product: SR32G
Revision: 8.6
Serial number: 0XA7F61DB1
Manufacturing date: 5/2022

FILE_SIZE_MB = 256
BUF_SIZE = 65536 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
924.33,109007,70819,70905
924.26,109215,70819,70910

Those bad performances are in line with very old versions of SdFat on the Pico (before 2.1.1).

Time ago, before SdFat v2.1.1, you kindly looked into those performances issues (I opened an issue at the time) and solved them in new versions.

Now it seems there's a regression of sort...?

I enabled ENABLE_DEDICATED_SPI and USE_SPI_ARRAY_TRANSFER in SdFatConfig.h with no results.

Any suggestion?
Many thanks,
Fernando

Looks like something may have changed in the RP2040 SPI driver. Array transfer(buf, count) is just a slow loop:

void SPIClassRP2040::transfer(void *buf, size_t count) {
    DEBUGSPI("SPI::transfer(%p, %d)\n", buf, count);
    uint8_t *buff = reinterpret_cast<uint8_t *>(buf);
    for (size_t i = 0; i < count; i++) {
        *buff = transfer(*buff);
        buff++;
    }
    DEBUGSPI("SPI::transfer completed\n");
}

However if I set:
#define USE_SPI_ARRAY_TRANSFER 2

For SdFat 2.2.3 I get:

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
2308.25,960,216,220
2310.39,1055,216,220

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
2307.19,257,214,221
2307.19,284,214,221

I don't try to define USE_SPI_ARRAY_TRANSFER for every board any longer since I have been burned by SPI driver changes.

You may be interested in the next SdFat-beta. It will be released soon and have RP2040 PIO SDIO.

Here are current results:
CPU 133MHz:

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
12819.69,2008,38,38
12657.42,2415,38,38

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
12593.65,77,39,39
12593.65,100,39,39](url)

CPU 250 MHz:

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
23472.68,1177,20,21
23472.68,1224,20,21

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
23695.17,58,21,21
23695.17,50,21,21

You may want to post a link to this on the arduino-pico site.

Looks like something may have changed in the RP2040 SPI driver. Array transfer(buf, count) is just a slow loop:

I will write Earle Philhower about this, thank you.

However if I set: #define USE_SPI_ARRAY_TRANSFER 2

For SdFat 2.2.3 I get:

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
2308.25,960,216,220
2310.39,1055,216,220

Indeed, with USE_SPI_ARRAY_TRANSFER 2 I got my old performances back (v2.2.2 here)!

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
2400.49,64444,27211,27302
2400.40,65321,27210,27303

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
2434.39,26943,26904,26922
2434.43,26941,26905,26921

Thank you!

You may be interested in the next SdFat-beta. It will be released soon and have RP2040 PIO SDIO.

I did read about that in another thread, this is absolutely great!
Unfortunately I need PIO to read from a parallel camera interface, so I have to use regular SPI to write to SD.

Unfortunately I need PIO to read from a parallel camera interface, so I have to use regular SPI to write to SD.

PIO SDIO uses one PIO. Does you camera use both PIO controllers?

PIO SDIO uses one PIO. Does you camera use both PIO controllers?

A the moment, yes (one to supply clocks and the other to read data), but it's still WIP, the goal is to use just one PIO. In this case your PIO SDIO would come very handy.