SD Performance

Hello,

Just getting started using the tinkerer kit, and I’ve been playing around with the SD card.

I wrote some code based on the example code given in the FEZ Beginners Guide to the .NET Micro Framework…The code simply writes to a FileStream object in a loop, until we’ve written 1 MB.

The program takes a lot longer to complete than I expected (around a minute). Is there any information available about SD write performance, optimizing writes, etc, etc? I’m new to the whole FEZ world, so I’m not sure what to expect.

Thanks,
Paul
Xerox Corporation

One minute fro one MB! That is not normal. Have you tried a different SD card? Have you tried formating the card before using it?

We see about 200K/sec on average and it worst case it is 50KB/sec. Read speed is a lot more. It think we got 800K to a MB/sec!

Maybe your code is processing something that is taking too long? Can you make a small demo and post the code here please?

Here’s the code I’m using.

The SD cards I have tested are:

Patriot 2GB SD (no class specification) : ~ 54 seconds
SanDisk 2GB micro SD (no class specification): ~33 seconds
SanDisk 4GB micro SDHC Class 2: ~33 seconds
SanDisk 4GB micro SDHC Class 4: ~23 seconds
Patriot 4GB micro SDHC Class 10: ~41 seconds

All cards had been been formatted before testing using FAT32.

using System;
using System.Threading;
using System.Text;
using Microsoft.SPOT;
using System.IO;
using Microsoft.SPOT.IO;
using GHIElectronics.NETMF.IO;

namespace FEZ_Panda_Application1
{
    public class Program
    {

        static void Main()
        {
            int i;
            byte[] ba = new byte[1024];
            DateTime start_time;
            DateTime end_time;
            TimeSpan ts;

            // Generate some junk to write
            for (i = 0; i < 1024; i++)
                ba[i] = (byte)(i % 255);

            PersistentStorage sdPS = new PersistentStorage("SD");

            sdPS.MountFileSystem();

            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;

            FileStream FileHandle = new FileStream(rootDirectory + @ "\hello.txt", FileMode.Create);

            start_time = DateTime.Now;
            for (i = 0; i < 1024; i++)
            {
                FileHandle.Write(ba, 0, 1024);
            }
            end_time = DateTime.Now;

            FileHandle.Close();
            sdPS.UnmountFileSystem();

            ts = end_time - start_time;
            Debug.Print(ts.ToString());

            // ...
            Thread.Sleep(Timeout.Infinite);
        }
    }
}

Thanks for any help,
Paul
Xerox Corporation

Your for loop is killing the performance. Try to use 2K array and cut “for loop” iterations in half and see the difference.

I also see the pattern with Patriot brand.

I doubt the issueis the for loop…

I wonder if there is some issue on boot. I would think it might take a while for the system to recognize the presence of the SD card.

There is a method to find out if a SD card is present. I would try a loop which waits the detection of the SD card, and then run the test.

Threre is the class of the SD card being used? An old card might be class 1, which is very slow. Try a few other cards.

I still would like to see the time difference with larger buffer and less iterations. If you can, please.

I didn’t see any difference with different buffer sizes.

Here are some results from various combinations of loop iterations and buffer size. All tests were run with a SanDisk 4 GB SDHC Class 4 part.

512 iterations of 2048 bytes: 29-34 seconds
1024 iterations of 1024 bytes: 29-34 seconds
2048 iterations of 512 bytes: 30-34 seconds

Thank you. I was wrong. See if Mike’s suggestion changes the picture.

I just tried the same test, but ran it twice back to back (without restarting the application). I’m assuming (perhaps incorrectly??) that this should eliminate the issue of boot delays / file system ready, etc.

First test ran in 34 seconds
Second test ran in 33 seconds.

So, it seems to fall within the same margin of error I’ve noticed with my previous tests.

Procedure:
Mount file system
Open File
Start 1st loop to write 1024 * 1024 (~34 sec)
Start 2nd loop to write 1024 * 1024 (~33 sec)
Close File
Unmount file system

Have you tried running the program without debugging?
You could write the timing values back to the SD card and run the board from an external power supply.

Let us try this here. The fastest we usually test on is FEZ Cobra with USB connection…

I got these results:
My configuration:
Panda, with DIY SD Card on the breakout board, connected the same way as
http://www.microframeworkprojects.com/index.php?title=SD_Card_Connection_Guide

And this is the code I used:


using System;
using System.IO;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;

using GHIElectronics.NETMF.Hardware;

using GHIElectronics.NETMF.USBHost;

namespace FEZ_Panda_Application1
{
    public class Program
    {
        static byte[] ba = new byte[1024];

        static DateTime start_time;
        static TimeSpan ts;

        public static void writeSD()
        {        
            // ...
            // SD Card is inserted
            // Create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");

            int i;

            for (i = 0; i < 1024; i++)
            {
                ba[i] = (byte)(i % 255);
            }
            
            // Mount the file system
            sdPS.MountFileSystem();

            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;

            FileStream FileHandle = new FileStream(rootDirectory + @ "\hello.txt", FileMode.Create);

            for (i = 0; i < 1024; i++)
            {
                FileHandle.Write(ba, 0, 1024);
            }

            FileHandle.Close();

            sdPS.UnmountFileSystem();
        }

        public static void Main()
        {
            //Start measure
            start_time = DateTime.Now;
            writeSD();
            ts = DateTime.Now - start_time;
            Debug.Print("Write file to SD in: " + ts);
        }

    }
}

I tried copying/pasting the code provided by Sam, and ran it on my Tinkerer kit. Ran the test three times, and got results in the 40-45 second range.

And, as suggested by Geir in an earlier post, I did try running outside the debugger, and wrote the results to the SD card. The results were no different than running with the debugger.

I’m going to keep playing around with things. If anyone can think of anything else to try in meantime, please let me know.

Thanks for the help,
Paul

Paul:
My code is not that different from yours!
I did moved most of the stuffs to writeSD() method, so we can see it better in the code.

Let’s wait for Mike’s result, and see what your problem might have been.

I know, but just wanted to eliminate another variable in case there was something stupid about my code.

I watched the YouTube video you posted in your earlier response. Unless I’m not understanding something, the hardware connections should be same between what was shown in the video, and what I have on my Panda base board, correct?

I could not confirmed that!
Since I do not have the schematic of the Panda base board.

That’s why I said that we have to wait for Mike’s result.

Schematics for base board:

[url]http://www.tinyclr.com/downloads/Panda/FEZ%20Panda%20base%201.1.pdf[/url]

Looks fairly straightforward…

Thanks for the schematics

It’s is exactly the same connections that I had.

I tried Peddy’s original code on a TwinMOS Ultra-X 1Gb 150x card and the write took 9.64 sec.
The card is formated as FAT16 (not FAT32).
It seems to be related to either the SD card type or the format. The code seems good.

One other variable is the hardware. It seems unlikely given the design, but more likely given the results, that maybe there is something about the specific build of the tinkerer board that is influencing the performance. I am really looking forward to hearing from GHI about what they are finding as they try to reproduce the results. I may have to buy one of the SD Expansion boards to hook straight up to a Panda and test.