slow sd/mmc interface

I was wondering why I'm seeing such slow write speeds to sd and mmc
cards using Linux on the Beagle. Tried multiple Linux git's, multiple
class 6 SD cards and version 4.2 MMC cards, multiple beagle boards.
Still writes go between 0.5 MB/s and 1.5 MB/s. Reads are several
multiples of time in magnitude faster. The cards them self write at
over 6MB/s on a PC? I'm wondering if this is this a limitation of
Linux or the OMAP hardware. Tried multiple changes to the Linux SD and
MMC drivers, but no substantial speed improvements.

Just wondering what's going on. It seems that writes should be a
littler faster than what I'm seeing.

Thanks to anyone in advance,

From over a year ago:



Koen, your figures are for read. Scott talks about writes.
Write are generally slower than reads.Guess it also has to do with erasing etc.
don't know exactly how much.

What definitely makes a difference is the block size with which you write
try dd with different bs values. (e.g. 1k, 4k, 16k, 1M)


I think I might have an inkling. I was doing some poking around with
a BeagleBoard's GPIO on the expansion header, and it seems there is a
4 MHz clock limiting the operation of the whole GPIO system. I am
working with a Debian 2.29 kernel. There may be a setting made to the
clock management system that is holding everything back. This might
have been intentional for portable systems to reduce power, but it is
a MASSIVE slowdown for wall-powered systems, slowing the GPIO to 1/150
of the CPU speed. So far, I have not been able to figure out where
the throttling is happening.


I'd like to run the same test program on my system, I have a feeling I
would not
get numbers anywhere this high.


I wrote a small program to buffer up random data to ram then time only
the write sequence, program below. I also used the dd utility to test.

# 1 MB write
dd if=/dev/zero of=/mnt/mmcblk0p1 bs=1024 count=1024

I'm seeing 0.5 MB/s with 1MB writes. Things speed up to around 1.5Mb/s
with larger writes of around 100MB at a time. Tried Adata, Transcend,
OCZ, and Ridata class 6 cards. All seem to give pretty consistent
results. Some are a little faster than others. Still between 0.5MB/s
and 1.5MB/s depending on write size, of course.

Hm. That indeed seems low.
CL6 cards are supposed to be able to do 6 MB/s

From wikipedia:
The SD Speed Class Ratings specify the following minimum write speeds
based on "the best fragmented state where no memory unit is

    * Class 2: 2 MByte/s - 13x
    * Class 4: 4 MByte/s - 26x
    * Class 6: 6 MByte/s - 40x

bs=024 might give you lower speeds but if you go to bs=1M or so, I
would expect things to go faster.

Don't forget that the file system on the card might also make a difference.
If you do a dd test you might want to do that to the raw device.

Btw, I tried your prog on the internal flash of my openrd board.
compiled with -O2.
root@OpenRD:~# ./tst 1048576 x
1048576 bytes written in 0.1149 Sec. = 0.870 MB/s
root@OpenRD:~# ./tst 10485760 x
10485760 bytes written in 1.544 Sec. = 6.477 MB/s

Don't ask me to explain the difference :slight_smile:
file system is ext3.
results are reproducable (within reasonable margin)
Don't have an empty SD card handy to test with.


PS: next time please attach code instead of inlining. Some lines with
strings were folded and needed editiing before I could compile.

Not sure how to attach code using this group. Please let me know how
and I will attach the source file. I tried the bs=1M and count=1,
close results to using 1K blocks and 1K count. Things really start
slowing down with block sizes below 1K, as I would expect. There is a
lot more overhead with very small block sizes. File system on the
cards is FAT32.



If you want to attach code, just send a mail to the list and use the
attach feature of your mailer. That should do it.
Not sure about the overhead for fat, you might want to test to write
to the raw device of an empty card (or perhaps partition)
e.g. /dev/sdX where X is the drive letter of your card.
Be warned that this will nuke whatever is on the card (but you can
always reformat so the card is not gone).
Not sure how much overhead the FAT filesystem gives (but ofc you can
also compare with ext2, ext3, ntfs, whatever)


Found the following TI "sprs518" data-sheet for the PSP Linux drivers
on an OMAP35x EVM.

I'm definitely not seeing the 6MB/s + that is bench marked in section
6.8.7. I wonder if the benchmark tests were measured with a lot of
caching? That is, I wonder if the program measuring the speed had a
sync() call at the end?

I had originally tried testing to the raw device. It doesn't seem to
make much of an improvement, so I went back to FAT32 a couple of days


Thanks for that link Scott. I found the newer Linux drivers release
document on the TI website. One thing they mentioned about the write/
read speeds in the NEWER document was this...

The performance numbers can be severely affected if the media is
mounted in sync mode. Hot plug
scripts in the filesystem mount removable media in sync mode to ensure
data integrity. For performance
sensitive applications, umount the auto-mounted filesystem and re-
mount in async mode.

I suggest trying in async mode and seeing what performance you guys
get. I plan on doing the same tests here in a little bit (couple


I guess a good question to ask would be. Are we measuring writes to
cache or measuring writes to the SD/MMC card at the point of mounting
using the -o async option? I wanted to write large files to the card
and umount quickly. I already got the response from TI to use the
async option. I think there may just be too much overhead running a
Linux OS on the OMAP to expect sustained 6MB/s write speeds. It
doesn't look like it's going to happen, bummer.

I checked using the async option. It flies on a 1MB write, but when I
run out of ram on larger sustained writes, or sync the fs, it's back
to the same old results.

time dd dd if=/dev/zero of=/mnt/mmcblk1p1/test.img bs=1048576

Completed in 2m12.578s, about 1.5MB/s write speed.


I see your point. One thing that looks some what good, atleast to my
application is that the write speeds seemed somewhat good for a USB
attached hard drive.

Got it. It was a Linux kernel configuration switch. Once I turned on
the bounce buffer switch MMC_BLOCK_BOUNCE, write speed increased 3
times. Not sure how this got tuned off. I believe it's turned on by
default in the beagle defconfig. Time to eat Crow!