Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 1 of 1

Thread: Simple SdFat write benchmark for T3.5/3.6

  1. #1
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    102

    Simple SdFat write benchmark for T3.5/3.6

    Curious about your T3.5/3.6 microSD write speed and write latency?

    Here's a simple benchmark, derived from https://github.com/greiman/SdFat/blo...sySdioDemo.ino

    Shows sequential write speed, average write latency (for given transfer size) and worst case write latency:

    Code:
    // SdFatSdioEx simple performance test for Teensy 3.5/3.6 onboard uSD
    #include "SdFat.h"
    
    #define SERIAL_SPEED 115200
    #define BLOCK_DIM 512
    // Check SD free space!
    #define PREALLOCATED_BLOCKS 512000UL  // 256 MB; compromise between statistics and total benchmark time
    #define BUF_DIM 256*BLOCK_DIM // 128KiB: will comfortably fit T3.5/3.6
    #define FILE_SIZE PREALLOCATED_BLOCKS*BLOCK_DIM
    
    SdFatSdioEX sdEx;
    File file;
    
    uint8_t buf[BUF_DIM];
    
    // buffer as uint32_t
    uint32_t* buf32 = (uint32_t*)buf;
    
    void errorHalt(const char* msg) 
    {
        sdEx.errorHalt(msg);
    }
    //------------------------------------------------------------------------------
    uint32_t kHzSdClk() 
    {
      return sdEx.card()->kHzSdClk(); 
    }  
    //------------------------------------------------------------------------------
    
    
    ////////////
    // RUNTEST
    ////////////
    
    void runTest() 
    {    
      // Fill buffer with 0
      memset(buf32, 0, sizeof(buf32));
      
      // Zero Stats
      uint32_t singleWriteMicros = 0;
      uint32_t maxSingleWriteMicros = 0;
      
      if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) 
      {
        errorHalt("open failed");
      }  
      Serial.println("\nPreallocating file (takes awhile)...\n");
      // Preallocate (off cycle)
      for (uint32_t i = 0; i < PREALLOCATED_BLOCKS; i++)
      {
        uint32_t nblocks = file.write(buf, BLOCK_DIM);
        if (nblocks != BLOCK_DIM)
        {
          errorHalt("Preallocation failed");
        }
      }
      file.rewind();
      Serial.println("Starting write benchmark");
      delay(2000);
      
      Serial.println("\nTransfer size\tWrite speed\tAvg write time\tMax write time");
      Serial.println("bytes\t\tKB/s\t\tus\t\tus\n");
      for (size_t nb = BLOCK_DIM; nb <= BUF_DIM; nb *= 2) 
      {
        maxSingleWriteMicros = 0;
        uint32_t nRdWr = FILE_SIZE/nb;
        Serial.print(nb);
        Serial.print("\t\t");
        uint32_t t = micros();
        for (uint32_t n = 0; n < nRdWr; n++) 
        {
          singleWriteMicros = micros();
          if (nb != file.write(buf, nb)) 
          {
            errorHalt("write failed");
          }
          singleWriteMicros = micros() - singleWriteMicros;
          if (singleWriteMicros > maxSingleWriteMicros)
            maxSingleWriteMicros = singleWriteMicros;
        }
        t = micros() - t;
        // Write speed
        Serial.print(1000.0f*FILE_SIZE/t, 1);
        Serial.print("\t\t");
        // Avg write time (us)
        Serial.print(t / nRdWr);
        Serial.print("\t\t");
        // Max write time (us)
        Serial.println(maxSingleWriteMicros);
        
        file.rewind();  // Ready for next write size
        t = micros();
      }
      file.close();
      Serial.print("\n SD clock speed (kHzSdClk): ");
      Serial.print(kHzSdClk());
      Serial.println(" KHz\n");
      Serial.println("Done");
    }
    //-----------------------------------------------------------------------------
    
    //////////
    //
    // SETUP
    //
    //////////
    
    void setup() 
    {
      Serial.begin(SERIAL_SPEED);
      while (!Serial);
      Serial.println("SdFatSdioEX write benchmark\nSdFatSdioEx uses extended multi-block transfers without DMA");
      
      if (!sdEx.begin()) 
      {
        sdEx.initErrorHalt("SdFatSdioEX begin() failed");
      }
      // make sdEx the current volume.
      sdEx.chvol();
      
      runTest();
    }
    //-----------------------------------------------------------------------------
    
    
    /////////
    //
    // LOOP
    //
    /////////
    
    void loop() 
    {
    }


    Results for my Teensy 3.6 overclocked to 240 MHz: card is an old Lexar 4GB class10 (not UHS):

    Code:
    SdFatSdioEX write benchmark
    SdFatSdioEx uses extended multi-block transfers without DMA
    
    Preallocating file (takes awhile)...
    
    Starting write benchmark
    
    Transfer size	Write speed	Avg write time	Max write time
    bytes		KB/s		us		us
    
    512		13227.7		38		94524
    1024		13316.5		76		94673
    2048		13483.4		151		9957
    4096		12967.5		315		97443
    8192		13206.4		620		95952
    16384		13214.3		1239		98412
    32768		13189.5		2484		98668
    65536		13071.9		5013		193157
    131072		13187.0		9939		106151
    
     SD clock speed (kHzSdClk): 48000 KHz
    
    Done
    Many thanks to Bill Greiman for his excellent SdFat library!
    Last edited by XFer; 11-04-2018 at 05:01 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •