Lexar 16GB Class 10 microSD Review

This is a rather old microSD card, which I had used very little as mobile storage. I expect it to behave as when it was new.

Lexar was a brand of Micron and has produced some flash drives/microSD cards that are not really usable for Raspberry Pi OS installs or even as adoptable storage for Android.
Lexar is now a brand of Longsys, a chinese company. Current microSD cards and USB drives may have no resemblance to the ones manufactured by Micron. I also can't seem to find these on sale on Amazon US.

Find on Amazon UK, in 32 to 512GB sizes: Lexar 633x microSDXC Card

Test Results

Page size:    4KiB
Block size:   4MiB
Open AUs (seq/random): 5/5
Read latency:          0.1ms (f3probe)
Seq. read:            20.40 MB/s
Seq. write, cache:    ----- MB/s
Seq. write, direct:   11.20 MB/s
Seq. write, ext4:     ----- MB/s
Random write   4KiB:   1.20 MB/s
Random write  16KiB:   4.54 MB/s
Random write  64KiB:   8.78 MB/s
Random write 512KiB:  12.07 MB/s

I actually tried using this as a Linux disk and it becomes remarkably slow with small writes. There is some garbage collection going on that kills performance in random ways, for minutes at a time. No amount of flash aware filesystems or using TRIM improved the situation. Only one I didn't try was Nilfs2, which may work slightly better but is not very well supported. 

Despite this, I have used it for some years now and it was quite reliable.

Testing Methodology

I use Flashbench, developed by Arnd Bergmann which can be downloaded from a forked branch at Github. The rest are standard Linux OS tools like 'dd', unless stated.

For full capacity verification, we use the "f3" utility developed by Digirati. It is available to download as a package for some Linux distributions or to compile from source.

I don't publish a result of "f3probe" unless the card reports fake capacity.

Sequential writes were performed with the 'dd' command, while varying the block size. At least 1GB is written to avoid effects of pseudo-SLC caches.

Observations

This is a rather old microSD card. Factoring shows smaller block size can be 1MiB:
$ factor 16012804096
16012804096: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 15271
16012804096 / 15271 = 1MiB
Now we analyse the flash structure with ‘flashbench’:

$ ./flashbench -c 32 -a /dev/mmcblk1 -b 1024
Aligned @ 4294967296 Delay: 1714870ns
Aligned @ 2147483648 Delay: 1933958ns
Aligned @ 1073741824 Delay: 2060743ns
Aligned @ 536870912  Delay: 1324035ns
Aligned @ 268435456  Delay: 1173544ns
Aligned @ 134217728  Delay: 1335984ns
Aligned @ 67108864   Delay: 1362197ns
Aligned @ 33554432   Delay: 1296054ns
Aligned @ 16777216   Delay: 1339159ns
Aligned @ 8388608    Delay: 1382772ns
Aligned @ 4194304    Delay: 1421637ns
Aligned @ 2097152    Delay: 802924ns
Aligned @ 1048576    Delay: 716409ns
Aligned @ 524288     Delay: 885901ns
Aligned @ 262144     Delay: 836088ns
Aligned @ 131072     Delay: 733568ns
Aligned @ 65536      Delay: 802411ns
Aligned @ 32768      Delay: 797909ns
Aligned @ 16384      Delay: 789915ns
Aligned @ 8192       Delay: 749787ns
Aligned @ 4096       Delay: 650218ns
Aligned @ 2048       Delay: 47241ns 

Measuring for 2KiB and 2MiB alignments shows intra-block access time drops. This should be an MLC drive, as it is rather old, so it can actually match the target 4KiB/4MiB sizes of the standard SD spec for page and erase block size.
Now, let’s look at sequential writes with ‘dd’, with 'O_DIRECT' writes:

  4 KiB =  2.00 MB/s
  8 KiB =  3.20 MB/s
 16 KiB =  5.80 MB/s
 32 KiB =  7.50 MB/s
 64 KiB =  8.70 MB/s
128 KiB =  9.40 MB/s
256 KiB = 10.40 MB/s
512 KiB = 10.80 MB/s
...
  2 MiB = 11.20 MB/s
  4 MiB = 11.20 MB/s

This is expected and if using a filesystem like ‘ext4’ it is beneficial to use ‘stripe=64’ to push at least 256KiB at once and keep write amplification down.

$ ./flashbench -c 32 /dev/mmcblk1 -f -b 4096 -e $(( 4 * 1024 * 1024 ))
4MiB    11M/s 12.8M/s  12.8M/s 12.8M/s 12.7M/s  12.8M/s  
2MiB    12M/s 12.6M/s  12.7M/s 12.8M/s 12.8M/s  12.7M/s  
1MiB    11.9M/s 12.8M/s  12.6M/s 12.8M/s 12.8M/s  12.8M/s  
512KiB  12M/s 12.7M/s  12.9M/s 12.6M/s 12.8M/s  12.8M/s  
256KiB  11.4M/s 12.4M/s  12.3M/s 12.4M/s 12.2M/s  12.3M/s  
128KiB  10.3M/s 11.6M/s  11.6M/s 11.7M/s 11.6M/s  11.5M/s  
64KiB   9.00M/s 10.2M/s  10.4M/s 10.5M/s 10.4M/s  10.4M/s  
32KiB   7.05M/s 8.4M/s   8.53M/s 8.33M/s 8.47M/s  8.46M/s  
16KiB   4.86M/s 6.3M/s   6.17M/s 6.27M/s 6.28M/s  6.22M/s  
8KiB    2.81M/s 3.63M/s  3.62M/s 3.6M/s 3.62M/s  3.61M/s  
4KiB    1.47M/s 1.94M/s  1.92M/s 1.92M/s 1.91M/s  1.92M/s

The first 4MiB are slower for smaller writes. Running with different offsets shows the same behavior, so there is no special area. I had observed this while running ‘dd’ writes.
It seems the controller tries to do something on the first 4MiB, but on TLC NAND it is usually a faster pSLC cache, not slower.

$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 2 * 1024 * 1024 )) \
-O --open-au-nr=5
2MiB    3.81M/s 
1MiB    12.6M/s 
512KiB  12.5M/s 
256KiB  12M/s   
128KiB  10M/s   
64KiB   9.09M/s 
32KiB   6.88M/s 
16KiB   4.75M/s 
8KiB    2.57M/s 
4KiB    1.33M/s 


$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 4 * 1024 * 1024 )) \
-O --open-au-nr=5
4MiB    9.42M/s 
2MiB    9.54M/s 
1MiB    12.3M/s 
512KiB  12.3M/s 
256KiB  11.7M/s 
128KiB  10.6M/s 
64KiB   9.05M/s 
32KiB   6.98M/s 
16KiB   4.85M/s 
8KiB    2.77M/s 
4KiB    1.43M/s

$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 4 * 1024 * 1024 )) \
-O --open-au-nr=6
4MiB    11.7M/s 
2MiB    4.27M/s 
1MiB    1.85M/s 
^C

$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 4 * 1024 * 1024 )) \
-O --open-au-nr=6 --random
4MiB    10.1M/s 
2MiB    3.68M/s 
^C

$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 4 * 1024 * 1024 )) \
-O --open-au-nr=5 --random
4MiB    9.84M/s 
2MiB    12.7M/s 
1MiB    12.4M/s 
512KiB  12.2M/s 
256KiB  11.7M/s 
128KiB  10.7M/s 
64KiB   9.06M/s 
32KiB   6.94M/s 
16KiB   4.7M/s  
8KiB    2.63M/s 
4KiB    1.06M/s 

$ ./flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 4 * 1024 * 1024 )) \
-O --open-au-nr=5 --random
4MiB    10.7M/s 
2MiB    12.2M/s 
1MiB    12.1M/s 
512KiB  12M/s   
256KiB  11.3M/s 
128KiB  10.2M/s 
64KiB   8.54M/s 
32KiB   6.48M/s 
16KiB   4.38M/s 
8KiB    2.47M/s 
4KiB    1.03M/s

$ /flashbench -c 32 /dev/mmcblk1 -b 4096 -e $(( 2 * 1024 * 1024 )) \
-O --open-au-nr=5 --random
2MiB    4.52M/s 
1MiB    12.6M/s 
512KiB  12.6M/s 
256KiB  5.64M/s 
128KiB  10.2M/s 
64KiB   9.36M/s 
32KiB   6.95M/s 
16KiB   4.71M/s 
8KiB    2.63M/s
4KiB    1.22M/s

No difference here, so I'd say 5 open AUs of 4MiB each.

No comments:

Post a Comment