1.はじめに
先日、@ai_raspberrypi様よりラズパイに使えるeMMCのレビューをしてみませんか?とのご連絡をいただきました。
最近の高級SBCは、eMMCを標準装備しているものも多くあり、Raspberry Piは公私ともによく使っている私としては興味津々です。喜んでレビューさせていただくことにしました。
試してみたのはこちらの「AdvaNceD IoT eMMC」というもので、容量は16GBのものです。MAKUAKEでもクラファン達成してますね。
訴求ポイントはこちらの3点の様です。
①はRaspberry Piを産業用途に使う際、常に言われることですね。ただ評価は難しいのが残念。
②については、お試し提供品なのでプリインストールされていませんでした。Raspberry Pi OSを自分でインストールして使ってみました。
③こちらのroot領域の保護機能というのも産業用途時に問題になりがちな話ですので期待しているのですが、まだ使えない様です。ただし、BADブロックが発生したときに自動的に修復する機能が動いているそうです(これもちょっと評価できないのですが)。
また、eMMCは(私が使っている様な安い)MicroSDと比較してアクセス速度が早そうなイメージがあるのでそこにも期待です。
2.結論
今回Raspberry PiをeMMCで動かしてみた率直な感想は次の通りです。
・ストレージへのアクセスは早い!(が、実用で実感するには用途を選びそう)
・rootの保護機能がとても気になるが試せなかったのが残念。
・メモリが大きくはみ出すので物理的なガードは必須。
ベンチマークツールを使ってeMMCとMicroSDカードの違いを確認したところ、ストレージの読み書きで大きな差がつくことが確認できました。
これまで、産業用途にラズパイを使用する際には、MicroSDカードのデータ破損を避けるためにROM化するなどMicroSDカードへのアクセスを最小限に抑えて運用することが定番でした。そのような運用方法の中ではこのメリットはなかなか生かせないのが残念です。一方、サーバ用途などでメモリスワップを多用するような場合は、このアクセス速度の向上の恩恵を受けられそうです。
また、今回実装されていないroot領域の保護機能が使い、破損を気にせずストレージをどんどんつかえば、アクセス速度の向上を実感できるかもしれません。
外形については、メモリのチップが大きくはみ出しているため運用上は何らかのガードを行うことが必須になろうかと思います。使用するケースによっては、スロットの奥まで挿入できず使用できないことも考えられるため注意が必要です。
3.外観
では外観を見てみます。端子面にはメモリチップが載っていてMicroSDスロット用の端子が伸びています。
チップ刻印は読めませんでしたが、中の情報を見るとToshibaのフラッシュメモリを使用している模様です。
ケースに入れたラズパイに挿入するとこんな感じです。一般的なプラスチックケースであれば挿入できないということは無さそう。私が保有する一部の金属ケースは、懐が深くSDスロットまでが遠いものがあったので注意が必要。
また、メモリがケースから飛び出した形状のため、何かにぶつけると容易に壊れてしまうことが予想されます。私は、過去にRaspberry Piに刺さったままのMicroSDカードが割れるという経験をしているため、この状態には大きな不安を感じます。実使用時には3Dプリンタなどでガード付きのケースを作ってガードしておいた方が良さそうです。
※参考:Raspberry Piに挿していただ状態で割れるMicroSD
raspi動かぬの一方をうけて駆けつけたらMicroSD割れてた。なぜ。 pic.twitter.com/d3AKuQZbRE
— airpocket (@AirpocketRobot) March 28, 2023
4.Windowsでベンチ
OSを書き込む前にCristalDiskMark8 でベンチをとってみました。
普段ベンチをとることなどないのでデータはうまく読めませんが、シーケンシャルリード以外はeMMCの勝ちでした。USB3.0のUSBカードリーダーを使っているので、そこはボトルネックになっていないと信じています。
比較対象のMicroSDカードはGIGASTONE製の16GB品です。
GIGASTONE 16GB UHS-I
eMMC
5.使ってみた
ベンチを見てなんとなく強そうな気がしてきましたが、まだよくわかりません。どんどん使っていきます。
OSを書き込んでみた
OSはRaspberry Pi OS Bullseye 64bit版を使います。
書き込みにかかる時間を計ってみました。
ストップウォッチで一回だけ計っただけですので、正確な数値ではありません。参考まで。
メディア | 書き込み時間 |
---|---|
eMMC | 3分57秒 |
MicroSD | 4分13秒 |
気持ちeMMCの方が早いのですが、一回だけの測定なので誤差範囲かもしれません。そもそも通常はOS書き込みを繰り返すこともないかと思いますので、あくまで参考です。CrystarDiskMarkの測定結果から想像するともっと差がついてもよさそうな気がしますので、書き込み速度以外の要因が大きいのでしょう。
起動してみた
ストップウォッチで計ってみた時間です。電源ONからデスクトップ表示までのおおよその時間です。
メディア | 起動時間 |
---|---|
eMMC | 27秒 |
MicroSD | 32秒 |
ベンチ回してみた
読み書き速度の違いが実運用に影響があるのか興味があるのでベンチも回してみました。
普段ベンチマークをとることが無いので、詳しい分析はできませんが、Unix BenchとPi Benchmarksで確かめました。
Unix bench
実行方法はこんな感じ。
git clone https://github.com/kdlucas/byte-unixbench
cd byte-unixbench/UnixBench
./Run
総合スコアだけ抽出してみましたが、大差はありません。
ストレージの読み書きは関係ない項目で評価している様です。
single core | multi core | |
---|---|---|
eMMC | 326.6 | 996.1 |
MicroSD | 322.0 | 978.3 |
全ての項目のスコアは次の通りです。
eMMC
------------------------------------------------------------------------
4 CPUs in system; running 1 parallel copy of tests
Dhrystone 2 using register variables 16369711.5 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2686.5 MWIPS (9.6 s, 7 samples)
Execl Throughput 1252.5 lps (29.8 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 145636.9 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 41234.4 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 425345.9 KBps (30.0 s, 2 samples)
Pipe Throughput 143292.8 lps (10.0 s, 7 samples)
Pipe-based Context Switching 31086.0 lps (10.0 s, 7 samples)
Process Creation 2016.9 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 2928.5 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 968.1 lpm (60.0 s, 2 samples)
System Call Overhead 103343.9 lps (10.0 s, 7 samples)
System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 16369711.5 1402.7
Double-Precision Whetstone 55.0 2686.5 488.5
Execl Throughput 43.0 1252.5 291.3
File Copy 1024 bufsize 2000 maxblocks 3960.0 145636.9 367.8
File Copy 256 bufsize 500 maxblocks 1655.0 41234.4 249.2
File Copy 4096 bufsize 8000 maxblocks 5800.0 425345.9 733.4
Pipe Throughput 12440.0 143292.8 115.2
Pipe-based Context Switching 4000.0 31086.0 77.7
Process Creation 126.0 2016.9 160.1
Shell Scripts (1 concurrent) 42.4 2928.5 690.7
Shell Scripts (8 concurrent) 6.0 968.1 1613.6
System Call Overhead 15000.0 103343.9 68.9
========
System Benchmarks Index Score 326.6
------------------------------------------------------------------------
4 CPUs in system; running 4 parallel copies of tests
Dhrystone 2 using register variables 63302604.2 lps (10.0 s, 7 samples)
Double-Precision Whetstone 10471.4 MWIPS (9.7 s, 7 samples)
Execl Throughput 3500.1 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 510461.9 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 155571.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 1150760.4 KBps (30.0 s, 2 samples)
Pipe Throughput 558124.8 lps (10.0 s, 7 samples)
Pipe-based Context Switching 96770.6 lps (10.0 s, 7 samples)
Process Creation 7212.7 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 7338.5 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 979.4 lpm (60.1 s, 2 samples)
System Call Overhead 403621.8 lps (10.0 s, 7 samples)
System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 63302604.2 5424.4
Double-Precision Whetstone 55.0 10471.4 1903.9
Execl Throughput 43.0 3500.1 814.0
File Copy 1024 bufsize 2000 maxblocks 3960.0 510461.9 1289.0
File Copy 256 bufsize 500 maxblocks 1655.0 155571.2 940.0
File Copy 4096 bufsize 8000 maxblocks 5800.0 1150760.4 1984.1
Pipe Throughput 12440.0 558124.8 448.7
Pipe-based Context Switching 4000.0 96770.6 241.9
Process Creation 126.0 7212.7 572.4
Shell Scripts (1 concurrent) 42.4 7338.5 1730.8
Shell Scripts (8 concurrent) 6.0 979.4 1632.3
System Call Overhead 15000.0 403621.8 269.1
========
System Benchmarks Index Score 996.1
microsd
------------------------------------------------------------------------
4 CPUs in system; running 1 parallel copy of tests
Dhrystone 2 using register variables 16191924.9 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2686.2 MWIPS (9.9 s, 7 samples)
Execl Throughput 1239.4 lps (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 142700.0 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 41840.9 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 407922.1 KBps (30.0 s, 2 samples)
Pipe Throughput 143459.0 lps (10.0 s, 7 samples)
Pipe-based Context Switching 31155.9 lps (10.0 s, 7 samples)
Process Creation 1959.6 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 2796.0 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 939.0 lpm (60.1 s, 2 samples)
System Call Overhead 103459.9 lps (10.0 s, 7 samples)
System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 16191924.9 1387.5
Double-Precision Whetstone 55.0 2686.2 488.4
Execl Throughput 43.0 1239.4 288.2
File Copy 1024 bufsize 2000 maxblocks 3960.0 142700.0 360.4
File Copy 256 bufsize 500 maxblocks 1655.0 41840.9 252.8
File Copy 4096 bufsize 8000 maxblocks 5800.0 407922.1 703.3
Pipe Throughput 12440.0 143459.0 115.3
Pipe-based Context Switching 4000.0 31155.9 77.9
Process Creation 126.0 1959.6 155.5
Shell Scripts (1 concurrent) 42.4 2796.0 659.4
Shell Scripts (8 concurrent) 6.0 939.0 1565.1
System Call Overhead 15000.0 103459.9 69.0
========
System Benchmarks Index Score 322.0
------------------------------------------------------------------------
4 CPUs in system; running 4 parallel copies of tests
Dhrystone 2 using register variables 63402783.2 lps (10.0 s, 7 samples)
Double-Precision Whetstone 10499.5 MWIPS (9.8 s, 7 samples)
Execl Throughput 3464.1 lps (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 505387.0 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 154520.8 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 1087853.5 KBps (30.0 s, 2 samples)
Pipe Throughput 558257.9 lps (10.0 s, 7 samples)
Pipe-based Context Switching 93079.3 lps (10.0 s, 7 samples)
Process Creation 6830.7 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 7216.1 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 953.3 lpm (60.1 s, 2 samples)
System Call Overhead 403354.5 lps (10.0 s, 7 samples)
System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 63402783.2 5433.0
Double-Precision Whetstone 55.0 10499.5 1909.0
Execl Throughput 43.0 3464.1 805.6
File Copy 1024 bufsize 2000 maxblocks 3960.0 505387.0 1276.2
File Copy 256 bufsize 500 maxblocks 1655.0 154520.8 933.7
File Copy 4096 bufsize 8000 maxblocks 5800.0 1087853.5 1875.6
Pipe Throughput 12440.0 558257.9 448.8
Pipe-based Context Switching 4000.0 93079.3 232.7
Process Creation 126.0 6830.7 542.1
Shell Scripts (1 concurrent) 42.4 7216.1 1701.9
Shell Scripts (8 concurrent) 6.0 953.3 1588.9
System Call Overhead 15000.0 403354.5 268.9
========
System Benchmarks Index Score 978.3
pi bench marks
実行方法です
sudo curl https://raw.githubusercontent.com/TheRemote/PiBenchmarks/master/Storage.sh | sudo bash
スコアだけを比較するとeMMCが大勝しました。
内容を見ると、全9項目中7項目がストレージへアクセスを伴うか、アクセス速度自体を評価したものでしたのでこの様な結果になった様です。
score | |
---|---|
eMMC | 4253 |
MicroSD | 581 |
eMMC
Category Test Result
HDParm Disk Read 40.28 MB/s
HDParm Cached Disk Read 41.76 MB/s
DD Disk Write 36.0 MB/s
FIO 4k random read 4733 IOPS (18932 KB/s)
FIO 4k random write 7074 IOPS (28297 KB/s)
IOZone 4k read 22302 KB/s
IOZone 4k write 18458 KB/s
IOZone 4k random read 12146 KB/s
IOZone 4k random write 20949 KB/s
Score: 4253
kingston sd
Category Test Result
HDParm Disk Read 40.96 MB/s
HDParm Cached Disk Read 39.83 MB/s
DD Disk Write 22.3 MB/s
FIO 4k random read 1338 IOPS (5352 KB/s)
FIO 4k random write 199 IOPS (798 KB/s)
IOZone 4k read 4492 KB/s
IOZone 4k write 1038 KB/s
IOZone 4k random read 4459 KB/s
IOZone 4k random write 463 KB/s
Score: 581
6.おまけ
AIの学習させたらメモリスワップで差がでないかと思ってfashion mnistさせてみたのですが、スワップ不要だった様で、学習時間に差はみられませんでした。
データベースを入れて表示に時間がかかっている案件があるので、環境をコピーして改善できないか試してみたいと思います。
eMMCを使用した場合
TensorFlow 2.12.0-rc0
Loading Fashion MNIST dataset...done
- Training dataset, images: (60000, 28, 28), labels: 60000
- Test dataset, images: (10000, 28, 28), labels: 10000
2023-04-07 09:30:40.050662: W tensorflow/tsl/framework/cpu_allocator_impl.cc:83] Allocation of 188160000 exceeds 10% of free system memory.
Epoch 1/10
1875/1875 [==============================] - 34s 17ms/step - loss: 0.4776 - accuracy: 0.8278
Epoch 2/10
1875/1875 [==============================] - 29s 16ms/step - loss: 0.3613 - accuracy: 0.8683
Epoch 3/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.3257 - accuracy: 0.8796
Epoch 4/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.3032 - accuracy: 0.8873
Epoch 5/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2853 - accuracy: 0.8925
Epoch 6/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2732 - accuracy: 0.8969
Epoch 7/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2600 - accuracy: 0.9028
Epoch 8/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2468 - accuracy: 0.9067
Epoch 9/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2360 - accuracy: 0.9102
Epoch 10/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2273 - accuracy: 0.9130
313/313 [==============================] - 2s 6ms/step - loss: 0.3581 - accuracy: 0.8815
test loss 0.35806766152381897, test accuracy 0.8815000057220459
313/313 [==============================] - 2s 6ms/step
predictions[0] : [1.7406170e-09 8.3751132e-07 1.1592202e-09 1.6522801e-08 3.0364036e-10
2.5482339e-05 3.2205685e-09 2.0332854e-04 1.0108462e-10 9.9977034e-01]
np.argmax(predictions[0]) : 9
test_labels[0] : 9
MicroSDの場合
TensorFlow 2.12.0-rc0
Loading Fashion MNIST dataset...done
- Training dataset, images: (60000, 28, 28), labels: 60000
- Test dataset, images: (10000, 28, 28), labels: 10000
2023-04-07 11:27:28.988779: W tensorflow/tsl/framework/cpu_allocator_impl.cc:83] Allocation of 188160000 exceeds 10% of free system memory.
Epoch 1/10
1875/1875 [==============================] - 35s 17ms/step - loss: 0.4798 - accuracy: 0.8244
Epoch 2/10
1875/1875 [==============================] - 30s 16ms/step - loss: 0.3577 - accuracy: 0.8670
Epoch 3/10
1875/1875 [==============================] - 28s 15ms/step - loss: 0.3263 - accuracy: 0.8796
Epoch 4/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.3014 - accuracy: 0.8888
Epoch 5/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2845 - accuracy: 0.8946
Epoch 6/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2710 - accuracy: 0.8977
Epoch 7/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2581 - accuracy: 0.9018
Epoch 8/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2451 - accuracy: 0.9068
Epoch 9/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2362 - accuracy: 0.9107
Epoch 10/10
1875/1875 [==============================] - 29s 15ms/step - loss: 0.2287 - accuracy: 0.9121
313/313 [==============================] - 2s 6ms/step - loss: 0.3501 - accuracy: 0.8818
test loss 0.3501115143299103, test accuracy 0.8817999958992004
313/313 [==============================] - 2s 6ms/step
predictions[0] : [4.2064581e-05 1.5370187e-04 9.7482378e-05 4.5203524e-05 4.5255461e-04
1.1994409e-02 1.0663022e-05 1.1742651e-01 3.9960719e-06 8.6977333e-01]
np.argmax(predictions[0]) : 9
test_labels[0] : 9
tensorflow環境の作り方
https://elchika.com/article/10487527-afbe-48c7-afc6-6c088a462a3c/
実行ソース
※こちらのサイトを参考に一部修正させていただきました。
https://qiita.com/hidakanoko/items/5292ca79e3ff53867e40#%E3%81%8A%E3%81%BE%E3%81%91
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
print("TensorFlow %s" % tf.__version__)
print("Loading Fashion MNIST dataset...", end="")
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
print("done")
print(" - Training dataset, images: %s, labels: %s" % (train_images.shape, len(train_labels)))
print(" - Test dataset, images: %s, labels: %s" % (test_images.shape, len(test_labels)))
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = train_images / 255.0
test_images = test_images / 255.0
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(256, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.optimizers.Adam(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=10)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print("test loss %s, test accuracy %s" % (test_loss, test_acc));
predictions = model.predict(test_images)
print("predictions[0] : %s" % predictions[0])
print("np.argmax(predictions[0]) : %s" % np.argmax(predictions[0]))
print("test_labels[0] : %s" % test_labels[0])
def plot_image(i, predictions_array, true_label, img):
predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
predictions_array, true_label = predictions_array[i], true_label[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions, test_labels, test_images)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, predictions, test_labels)
plt.show()