FatFS performance

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: utzig, lbednarz, tfAteba, barthess, RoccoMarco

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

FatFS performance

Postby iggarpe » Mon Nov 12, 2012 4:41 am

Hi all,

I'm using ChibiOS 2.4.x and the included patched FatFS library on a STM32F407V based board in which I have a microSD card connected to SPI1, and I'm quite disappointed with the write performance. I've implemented a few benchmark tests and these are the results:

Raw read/write (using the MMC driver sequential read/write functions):

Read: ~1700 KB/s
Write: ~1500 KB/s

File read/write (using FatFS):

Read: ~750 KB/S
Write: ~80 KB/S (!!!)

Now, I know there are mechanisms in a file system implementation that will inherently reduce the I/O performance, from cluster table maintenance to non-sequential read/write, but to me a slowdown from 1500 to 80 KB/s is a bit surprising, isn't it?

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: FatFS performance

Postby mabl » Mon Nov 12, 2012 8:07 am

Do you read each byte separately? There is a nice benchmark by elm chan:

Image

User avatar
Tectu
Posts: 1226
Joined: Thu May 10, 2012 9:50 am
Location: Switzerland
Contact:

Re: FatFS performance

Postby Tectu » Mon Nov 12, 2012 1:31 pm

Can you show us your benchmarking code?


~ Tectu

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: FatFS performance

Postby iggarpe » Mon Nov 12, 2012 1:54 pm

Code: Select all

Can you show us your benchmarking code?


Sure, I did not cut&paste it because it's pretty much trivial:

Raw MMC read benchmark:

Code: Select all

    chprintf(chp, "Reading %u sectors starting at sector %u\r\n", count, sector);
   
    start = chTimeNow();
   
    if (mmcStartSequentialRead(&MMCD1, sector)) {
      chprintf(chp, "ERROR: cannot start sequential read\r\n");
      return 1;
    }
   
    for (; count > 0; count--, size += MMC_SECTOR_SIZE)
      mmcSequentialRead(&MMCD1, (uint8_t *)shell_buf);
   
    if (mmcStopSequentialRead(&MMCD1)) {
      chprintf(chp, "ERROR: cannot stop sequential read\r\n");
      return 1;
    }
   
    elapsed = chTimeNow() - start;


Raw MMC write benchmark:

Code: Select all

    chprintf(chp, "Writing %u sectors starting at sector %u\r\n", count, sector);

    memset(shell_buf, value, MMC_SECTOR_SIZE);
    start = chTimeNow();
   
    if (mmcStartSequentialWrite(&MMCD1, sector)) {
      chprintf(chp, "ERROR: cannot start sequential write\r\n");
      return 1;
    }
   
    for (; count > 0; count--, size += MMC_SECTOR_SIZE)
      mmcSequentialWrite(&MMCD1, (uint8_t *)shell_buf);
   
    if (mmcStopSequentialWrite(&MMCD1)) {
      chprintf(chp, "ERROR: cannot stop sequential write\r\n");
      return 1;
    }
   
    elapsed = chTimeNow() - start;


File read benchmark:

Code: Select all

    chprintf(chp, "Reading from file '%s'\r\n", argv[1]);
   
    res = f_open(&fil, argv[1], FA_READ | FA_OPEN_EXISTING);
    if (res != FR_OK) {
      chprintf(chp, "ERROR opening: %s\r\n", fss_strerr(res));
      return 1;
    }
   
    start = chTimeNow();
   
    for (;; size += len) {
      res = f_read(&fil, shell_buf, MMC_SECTOR_SIZE, &len);
      if (res != FR_OK) {
        chprintf(chp, "ERROR reading: %s\r\n", fss_strerr(res));
        f_close(&fil);
        return 1;
      }
      if (len == 0) break;
    }
   
    elapsed = chTimeNow() - start;
    f_close(&fil);


File write benchmark:

Code: Select all

    chprintf(chp, "Writing %u bytes 0x%.2x to file '%s'\r\n", count, value, argv[1]);
   
    res = f_open(&fil, argv[1], FA_WRITE | FA_OPEN_ALWAYS);
    if (res != FR_OK) {
      chprintf(chp, "ERROR opening: %s\r\n", fss_strerr(res));
      return 1;
    }
   
    memset(shell_buf, value, MMC_SECTOR_SIZE);
    start = chTimeNow();
   
    for (;; count -= len, size += len) {
      len = count;
      if (len > MMC_SECTOR_SIZE)
        len = MMC_SECTOR_SIZE;
      res = f_write(&fil, shell_buf, len, &len);
      if (res != FR_OK) {
        chprintf(chp, "ERROR writing: %s\r\n", fss_strerr(res));
        f_close(&fil);
        return 1;
      }
      if (len == 0) break;
    }
   
    elapsed = chTimeNow() - start;
    f_close(&fil);

User avatar
Tectu
Posts: 1226
Joined: Thu May 10, 2012 9:50 am
Location: Switzerland
Contact:

Re: FatFS performance

Postby Tectu » Mon Nov 12, 2012 2:01 pm

I am currently on the road and therefore can not properly check your code, but I will try this out tonight for you so I can give you a few reference results ;-)


~ Tectu

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: FatFS performance

Postby iggarpe » Tue Nov 13, 2012 6:43 pm

No one has any performance figures ?

Abhishek
Posts: 266
Joined: Wed May 23, 2012 3:15 pm
Location: India

Re: FatFS performance

Postby Abhishek » Wed Nov 14, 2012 11:36 am

Hello iggarpe,

A few months ago I used a SD card connected to SPI1 of a Discovery board to display images on a LCD screen, I can only provide read figures.

It takes about 20081596 cycles or about 120ms (~8.4 fps) for a full screen image of , running on a F4Discovery @ 168MHz with a 2048 byte read buffer. The image size is 150 KB exactly. So with that it comes to be around 1.22 MB/s. When I used a larger buffer of size 16 KB, it went to 16007733 clock cycles (95 ms, 10.5 fps). This gives the read speed to be 1.54 MB/s . Note that this test has been done with ChibiOS 2.4.1, latest ChibiOS versions have a newer 'block device' implementation, I have not played around with that. The speed varies a lot depending on the SD card being tested and the compiler being used, the optimizations applied.

The read speed seems to depend a lot on the size of the read buffer, and whether the read you are doing is sector aligned (with a multiple of 512) or not. Even a misalignment of 1 byte causes a very significant loss of speed.

You could try increasing the read buffer size and see if it leads to any performance improvement.

Best Regards
Abhishek

User avatar
Prof. Dr. YoMan
Posts: 57
Joined: Thu May 24, 2012 11:00 am
Been thanked: 1 time

Re: FatFS performance

Postby Prof. Dr. YoMan » Wed Nov 14, 2012 2:15 pm

I guess the problem is not the read speed. Which seems ok for him, but ...
Write: ~80 KB/S (!!!)

mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Location: Karlsruhe, Germany
Been thanked: 1 time
Contact:

Re: FatFS performance

Postby mabl » Wed Nov 14, 2012 4:16 pm

On the other hand, the Write performance does only depend on the card - the SPI data rate should be the same for both directions, shouldn't it? And given that it only shows with fatfs - maybe the FAT is not aligned or something? Or try another card?

User avatar
Giovanni
Site Admin
Posts: 13064
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 636 times
Contact:

Re: FatFS performance

Postby Giovanni » Wed Nov 14, 2012 4:20 pm

The problem I see is that, unless I am missing something, FatFS does not have a proper buffers cache so it has to read/write FAT sectors continuously while performing a large sequential write.

Giovanni


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 12 guests