IoT用SDカード選択に潜む罠（？）

# SDカードの速度
SD(SDHC, microSDなど含む)カードの速度は通常パッケージにClass10などのように記載されているが、これは通常読み取り速度についてのみ触れられている。
IoT機器で利用する際になんとなくSDカードを選ぶと思わぬ罠が待っていることがあるかもしれない。

# おことわり
このテストは2013年ごろにRaspberry Pi用に行ったテストで得られた知見を元に行ったものなので、現在店頭で手に入るもので同じ結果が得られるとは限らない。

# テスト方法
## fioによるベンチマーク
I/O速度をベンチマークするfioによりテストを行う。
複数の項目を個別にテストすると手間がかかるため、下記のジョブファイルとバッチファイルにより連続して処理を行う。

```:fio.job
[seqread]
readwrite=read
blocksize=1m
size=100m
directory=./
direct=1
loops=5

[seqwrite]
readwrite=write
blocksize=1m
size=100m
directory=./
direct=1
loops=5

[seqread4]
readwrite=read
blocksize=1m
size=100m
directory=./
direct=1
numjobs=4
loops=5
group_reporting

[seqwrite4]
readwrite=write
blocksize=1m
size=100m
directory=./
direct=1
numjobs=4
loops=5
group_reporting

[randread512k]
readwrite=randread
blocksize=512k
size=100m
directory=./
direct=1
loops=5

[randwrite512k]
readwrite=randwrite
blocksize=512k
size=100m
directory=./
direct=1
loops=5

[randread4k]
readwrite=randread
blocksize=4k
size=10m
directory=./
direct=1
loops=3

[randwrite4k]
readwrite=randwrite
blocksize=4k
size=10m
directory=./
direct=1
loops=3

[randread4k32]
readwrite=randread
blocksize=4k
size=10m
directory=./
direct=1
numjobs=32
loops=3
group_reporting

[randwrite4k32]
readwrite=randwrite
blocksize=4k
size=10m
directory=./
direct=1
numjobs=32
loops=3
group_reporting
```

```bash:fiobatch.sh
#!/bin/sh
echo "job, bandwidth, iops"
fio --section=seqread  --minimal fio.job |  awk -F';' '{print "seqread, " $7 ", " $8}'
rm -f seqread.*.0
fio --section=seqwrite  --minimal fio.job |  awk -F';' '{print "seqwrite, " $48 ", " $49}'
rm -f seqwrite.*.0
fio --section=seqread4 --minimal fio.job |  awk -F';' '{print "seqread4, " $7 ", " $8}'
rm -f seqread4.*.0
fio --section=seqwrite4 --minimal fio.job |  awk -F';' '{print "seqwrite4, " $48 ", " $49}'
rm -f seqwrite4.*.0
fio --section=randread512k  --minimal fio.job |  awk -F';' '{print "randread512k, " $7 ", " $8}'
rm -f randread512k.*.0
fio --section=randwrite512k --minimal fio.job |  awk -F';' '{print "randwrite512k, " $48 ", " $49}'
rm -f randwrite512k.*.0
fio --section=randread4k  --minimal fio.job |  awk -F';' '{print "randread4k, " $7 ", " $8}'
rm -f randread4k.*.0
fio --section=randwrite4k --minimal fio.job |  awk -F';' '{print "randwrite4k, " $48 ", " $49}'
rm -f randwrite4k.*.0
fio --section=randread4k32  --minimal fio.job |  awk -F';' '{print "randread4k32, " $7 " ," $8}'
rm -f randread4k32.*.0
fio --section=randwrite4k32 --minimal fio.job |  awk -F';' '{print "randwrite4k32, " $48 ", " $49}'
rm -f randwrite4k32.*.0
```

\$7, \$8, \$48, \$49は*minimalオプション*を指定した場合にリード/ライトのバンド幅とIOPSが記録されている場所になる。[fioのマニュアル](https://linux.die.net/man/1/fio)にも記載があるが、数字との対応がわかりにくいので[こちら](https://www.andypeace.com/fio_minimal.html)を参照した方がいい。

試しにシステムのSSDで試すと以下のようになった。bandwidthはkB/s。

```:PLEXTOR_PX-256M5
# ./fiobatch.sh
job, bandwidth, iops
seqread, 249512, 243
seqwrite, 225550, 220
seqread4, 270827, 264
seqwrite4, 253183, 247
randread512k, 215306, 420
randwrite512k, 211221, 412
randread4k, 19068, 4767
randwrite4k, 33610, 8402
randread4k32, 115801 ,28950
randwrite4k32, 133185, 33296
```

## SDカードでのテスト結果
手元にある各種SDカードで試した結果は以下のようになる。SDカードはすべてext4でフォーマットしている。またPCとの接続は[BSCRA35U2](http://buffalo.jp/products/catalog/supply/peripheral/cardreader/cardreader/bscra35u2/)を利用した。

### Panasonic
#### RP-SDAB08GJK
```
job, bandwidth, iops
seqread, 18729, 18
seqwrite, 15256, 14
seqread4, 19788, 19
seqwrite4, 5286, 5
randread512k, 19896, 38
randwrite512k, 3467, 6
randread4k, 2883, 720
randwrite4k, 53, 13
randread4k32, 2788 ,697
randwrite4k32, 50, 12
```

#### RP-SDWA08GJK
```
job, bandwidth, iops
seqread, 16447, 16
seqwrite, 7962, 7
seqread4, 19510, 19
seqwrite4, 1490, 1
randread512k, 18579, 36
randwrite512k, 701, 1
randread4k, 1656, 414
randwrite4k, 89, 22
randread4k32, 1871 ,467
randwrite4k32, 69, 17
```

### SanDisk
#### Extreme Pro
```
job, bandwidth, iops
seqread, 18830, 18
seqwrite, 18089, 17
seqread4, 20757, 20
seqwrite4, 19196, 18
randread512k, 20278, 39
randwrite512k, 8039, 15
randread4k, 4237, 1059
randwrite4k, 1331, 332
randread4k32, 4250 ,1062
randwrite4k32, 873, 218
```

### SONY
#### SF-8UX
```
job, bandwidth, iops
seqread, 17646, 17
seqwrite, 14699, 14
seqread4, 20171, 19
seqwrite4, 16737, 16
randread512k, 19690, 38
randwrite512k, 7637, 14
randread4k, 3449, 862
randwrite4k, 784, 196
randread4k32, 3683 ,920
randwrite4k32, 190, 47
```

### TOSHIBA
#### SD-T16GR6WA2
```
job, bandwidth, iops
seqread, 17486, 17
seqwrite, 11461, 11
seqread4, 18598, 18
seqwrite4, 3474, 3
randread512k, 20010, 39
randwrite512k, 2246, 4
randread4k, 3904, 976
randwrite4k, 137, 34
randread4k32, 4014 ,1003
randwrite4k32, 77, 19
```

### BUFFALO
#### RSDC-16GC10/E
```
job, bandwidth, iops
seqread, 13289, 12
seqwrite, 4985, 4
seqread4, 13143, 12
seqwrite4, 1156, 1
randread512k, 15438, 30
randwrite512k, 726, 1
randread4k, 2394, 598
randwrite4k, 5, 1
randread4k32, 2311 ,577
randwrite4k32, 5, 1
```

# まとめ
シーケンシャルリードはおそらくUSB 2.0接続しているカードリーダの性能上限に達しているため、速度がほぼ変わらないと思われる。
注目してもらいたいのはランダムライト性能でこの値はSDカードによって大きく異なる。
IoT機器では極力ストレージに書き込まないようにするものかもしれないが、とりあえず。
最もランダムライト性能の悪かったBUFFALOのSDカードだが、通常のデジカメなどであれば問題の無い速度が出ているため、粗悪品というようなことはない。だたし用途によっては注意が必要。