« 粗大ごみの回収に向けて | トップページ | Intel(ALTERA)のMAX10キットを試す »

2018.12.05

ZYNQ LinuxからのUSBメモリ書き込み速度

ZynqとLinuxで計測システムを作ったときに、どのくらいの速度で記録ができるのかという疑問を晴らすために、Zynq LinuxからUSBメモリに書き込む速度を測定してみました。

使用したZYNQのシステムは、Cosmo-Z Mini

Zynq_usbmem

この中にはXC7Z020が入っていて、Ubuntu Linux 14.04が起動しています。

いろいろなメモリカードやUSBメモリを用意しました。

  • TOSHIBAの32GB USBメモリ
  • SDカードリーダとTOSHIBAの16GB MicroSD (秋月)
  • Buffaloの8GB USBメモリRUF3-K8GA-BK

Zynq_usbmem1

これらのメモリにデータを書き込むわけですが、一番シンプルなのはddコマンドを使って乱数を書き込む方法です。

dd if=/dev/urandom of=/usbmem/test.bin bs=1048576 count=12000

結果の表示は 

・・・
12577055296 バイト (13 GB) コピーされました、 947.968 秒、 13.3 MB/秒

これではあまりにもシンプルすぎてつまらないので、自分でプログラムを作って書き込むことにしました。

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <cstdlib>

const long long blocksize = 1000000;

void showspeed(struct timeval* start, int block) {
	struct timeval current;
	gettimeofday(&current, NULL);
	printf("%lld\t", (long long)blocksize * block / 1000000);
//	printf("Total %lld[MB],", (long long)blocksize * block / 1000000);
	printf("%ld\t", current.tv_sec - start->tv_sec);
//	printf("%ld[sec]", current.tv_sec - start->tv_sec);
	if(current.tv_sec != start->tv_sec) {
		double elapsed = (current.tv_sec - start->tv_sec) * 1000000 + (current.tv_usec - start->tv_usec);
		printf("%3.2f\n", (double)(blocksize * block) / elapsed);
//		printf(", Write throughput=%3.2fMB/s\n", (double)(blocksize * block) / elapsed);
	}
	else {
		printf("\n");
	}
}

int main(int argc, char *argv[]) {
	struct timeval start;

	if(argc < 3) {
		printf("usage: memfill size(GB) filename\n");
		return 1;
	}
	double size = atof(argv[1]);
	char *filename = argv[2];

	unsigned char *tmp = new unsigned char [blocksize];
	for(int j=0;j<blocksize;j++) {
		tmp[j] = rand();
	}

    std::ofstream ofs(filename,std::ios::out | std::ios::trunc | std::ios::binary);
    if (!ofs) {
        std::cerr << "error" << std::endl;
        std::exit(EXIT_FAILURE);
    }

	printf("[MB]\t[sec]\t[MB/sec]\n");

	gettimeofday(&start, NULL);
	int block;
	for(block = 0; block < size * 1000 ; block++) {
		if((block % 100) == 0) {
			showspeed(&start,block);
		}
		ofs.write((char *)tmp,blocksize);
	}
	showspeed(&start,block);

	ofs.close();
	
	delete[] tmp;
}
 

ddと比べても速度に差はなかったので、このプログラムで計測することにしました。

このプログラムを実行すると次のような表示が出ます。

Zynq_usbmem4

100MB書き込んだときは平均23.32MB/sで、500MBのときは平均14.94MB/sで、というふうに読みます。最初はおそらくキャッシュが効いていて速いのですが、だんだん遅くなってくるのがわかります。

書き込み速度のグラフを示します。

Zynq_usbmem2

サイズが大きくなるとだんだん遅くなるのがわかりますね。このまま12GBまで続けてもそれほど変わらないので、2GBで打ち切っています。

下のほうを拡大してみます。

Zynq_usbmem3

one 意外なことに、一番速かったのは、秋月で売っている東芝のMicroSDカードをext4でフォーマットしてUSBカードリーダに挿したものでした。14GB/s出ています。このMicroSDカードをFAT32にするとわずかに遅くなります。

two 次点はBuffaloのUSBメモリ(RUF3-K8GA-BK)をext4でフォーマットしたもの(水色)なのですが、RUF3-K8GA-BKはFAT32にすると激遅(黄色の線)になります。

RUF3-K8GA-BKはUSB3.0のインタフェースを積んでいるくせに、Windowsパソコンから書き込んでも7MB/secしか出ません。Amazonのレビューでも遅さが指摘されています。

three Cosmo-Z Miniは4GBのeMMCを積んでいるのですが、意外と遅いようです。10MB/sec前後です。

four しかし、一番遅いのはWindowsで使いまわしている東芝のUSBメモリで、すでにいろいろなファイルが入っているものです。

結論を言うと、

  • USBメモリの種類によってかなりばらつきがある。東芝のMicro USB速い!
  • ext4でまっさらな状態にフォーマットして使うと速くなる
  • すでに使用中のUSBメモリカードに追記すると遅くなる

という感じでした。

メモリカードと機材を選べば10MB/s以上で連続してデータを記録できそうですね。

|

« 粗大ごみの回収に向けて | トップページ | Intel(ALTERA)のMAX10キットを試す »

コメント

>14GB/s出ています。
むちゃくちゃ速いですね

投稿: のなめ | 2018.12.08 10:14

コメントを書く



(ウェブ上には掲載しません)




« 粗大ごみの回収に向けて | トップページ | Intel(ALTERA)のMAX10キットを試す »