5778209 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

ふるた技工所(てっこうしょ)

PR

全880件 (880件中 1-10件目)

1 2 3 4 5 6 ... 88 >

ソフト開発日誌

2021.04.04
XML
カテゴリ:ソフト開発日誌
KBN-I-5200 が動かなくなってしまったため、代わりの ITX フォームファクタマザーボードを探す。ファンレスの方が都合が良いので ASRock J5040-ITX を選ぶ。



基板を見ると eMMC が乗りそうなランドがヒートシンクの脇に見える。M.2 スロットが WiFi になっているのは、ここに eMMC を乗せるから、SSD は被る機能だと考えたのかもしれない。

Pentium Silver J5040の仕様を読むと RAM は最大 8GiByte だ。J5040-ITX 対応メモリに 16Gibyte の SO-DIMM が入っている。しかも 2 枚差し対応だ。どういうこと?



何か変だなと思いつつ。Crucial CT2K16G48FD8266 を買ってしまった。16Gibyte x 2 で、基板両面にチップが乗る。バスの負荷は最大で重い構成だ。

2 枚組にパッケージされていたメモリは CT16G4SFD8266.C16FN だった。メモリのサポートリストに載っていないな...



組み立てて動かしてみると、直ぐに画面が出ない。ああ、組み合わせ悪かったかな?と思い何度か電源を入れ直す。うーん。ボダン電池付け直し、C-MOS クリアジャンパ掛けを試した後、何回目かの電源投入をして「どうしよう」と放置していたら、BIOS (とは最近言わないのか UEFI だっけ)の初期化進行メッセージが出始めた。

1 ~ 2 分くらい待たないと、DRAM 信号キャリブレーション(あるいはトレーニング)が終わらないのか。まぁ、そうだろうな。Intel の仕様を越える様なことをしているのだから、Firmware で色々と処理を補っているのかも。

1 回起動に成功すると、その後は 5 秒くらいで起動する。パラメータを覚えているようだ。

MemTest86 (+ は付かない方) でメモリテストを実施する。PASS した。alias している心配も無い。UEFI 対応の MemTest86 の方が起動は簡単だ。Memtest86+ だと UEFI 対応していないのか、そもそも起動候補にも出てこない。PXE boot も UEFI 対応が必要みたいだ。



MemTest86 実行中はヒートシンクに弱くても良いので、風を当てた方が良い。無風で 22 ℃ほどの室内で MemTest86 を実行していたら 94 ℃まで CPU 温度が上昇した。Junction 温度 105 ℃なので、余裕は 10 ℃くらいだ。温度の読みはそれ程正確ではない。ほどよい風量の USB 扇風機で風を当てて、Memtest86 実行中は 60 ~ 62 ℃に CPU 温度を押さえた。

TDP 10W って本当かなぁ。






最終更新日  2021.04.05 01:30:28
コメント(0) | コメントを書く


2020.10.12
カテゴリ:ソフト開発日誌
在宅勤務で家庭内 LAN 環境を変更する必要が出てきた。具体的には LAN - Router - WAN だった単純なネットワーク環境に、WAN には繋がらない閉じた LAN 環境を追加した。

いくつかのマシンに LAN Adapter を追加して、閉じた LAN 側に接続する。USB - Ethernet Adapter を買う。せっかくなので Super Speed USB to Gigabit Ethernet Adaper を選ぶ。



あー、Linux (Ubuntu 18.04 x64) で繋がるのかなぁ... 心配なので 2 品種買うことにした。



どちらも繋がることが分かった。Linux 認識の列にあるリンクは dmesg, ethtool で認識結果を確認したコンソールログだ。
メーカー型名Linux 認識
BUFFALOLUA4-U3-AGTE-WHax88179_178a
TP-LinkUE300r8152

LED の点き方は LUA4-U3-AGTE-WH は状態確認重視だ。



UE300 はデザイン重視、どこがどう光るかは点いてみないと分からない。パケットが通ると点滅する。



もともと自分でも WAN 側から LAN 側への入り方、忘れるくらい面倒な家庭内 LAN なんだよなぁ...






最終更新日  2020.10.12 02:24:26
コメント(0) | コメントを書く
2020.08.20
カテゴリ:ソフト開発日誌
MO メディアをサルベージしていたら、懐かしいコードが見つかる。筆算方式で uint32_t (32 bit で表した正の整数) の平方根を求めるコードだ。8086 Assembler のコードで記述してある。アルゴリズムの概要をコメントに書いてあるので他の言語やアセンブラでも容易に書き直せると思う。

ideal
model   small,c
codeseg

;in A
;
; X=0
; w=0
; Count=16
; @@l1:
; w<<=1
; X<<2bit<<A
; save X
; X-=(w+1)
; if cond CY
;       {recover X
;       }
;   else
;       {w|=2;
;       }
; LOOP @@l1;
; w>>1 -> ans

;in     dx:ax
;
proc    NOLANGUAGE sqrroot
xor     si,si   ;bl:si  X
xor     di,di   ;bh:di  w
mov     cx,10h
mov     bh,0c0h
jmp     @@l0in
even
@@l0:
dec     cx
jz      @@exit
shl     ax,1
rcl     dx,1
shl     ax,1
rcl     dx,1
@@l0in:
test    dh,bh
jz      @@l0
xor     bx,bx
even
@@l1:
shl     di,1
rcl     bh,1
shl     ax,1
rcl     dx,1
rcl     si,1
rcl     bl,1
shl     ax,1
rcl     dx,1
rcl     si,1
rcl     bl,1
push    si
push    bx
stc
sbb     si,di
sbb     bl,bh
jnb     @@j1
pop     bx
pop     si
loop    @@l1
shr     bh,1
rcr     di,1
mov     ax,di
ret
@@j1:
add     sp,4
inc     di
inc     di
loop    @@l1
shr     bh,1
rcr     di,1
mov     ax,di
@@exit:
ret
endp
even

public  ulsqrroot
proc    ulsqrroot
arg     @@a:dword
uses    si,di
mov     dx,[word high @@a]
mov     ax,[word low  @@a]
call    sqrroot
ret
endp
even
end

コメントのアルゴリズムに対し、実装は上位桁に 0 が続く場合、計算を少し速くする工夫がある。それ以上の変わった処理やアセンブラ独特の高速化は導入していない素朴な処理だ。

今時は浮動小数点計算がお手軽に使えるし、8 ~ 16 bit の組み込みマイクロプロセッサもメーカーが実装例を示しているので、開平処理を態々書くことも無いか。

これをテストするコードは C 言語で書いてあった。分かりやすく書き直してテストしてみる。

ビルドできて、実行すると期待通りの動作をした。Borland C++ 3.1 (TASM, BCC, MAKE, TLINK) でビルドできるソースコード一式を作る。ビット化け、重複、欠落を起こさずに MO から読み出せていた。

今でも懐かしく思えで、動かそうかなと思うコードってそんなに多くないのかな。






最終更新日  2020.08.20 22:06:00
コメント(0) | コメントを書く
2020.08.19
カテゴリ:ソフト開発日誌
暫く日記をサボっているのでネタ発掘。いつ買ったのか調べたくて、食品温度計(あるいは調理用温度計、クッキング温度計)を検索してみる。始めに次の画像で検索してみた。



タイルの壁をバックに何がトイレットペーパーホルダーや手すり、ちょっとした壁掛け小物入れが写った画像が類似画像として見つかった。

もしかしたら、google 画像検索エンジンが賢くなって、結果が変わっているかもしれない。

なるほど、背景に写る工作用紙の方眼がタイルに見えたのか。背景・食品温度計のどちらも画像の文脈だと捉えて、背景はタイル、食品温度計はタイルに接近して存在する器物に近い何かだと判断して検索したのか。両方の文脈を満たす画像の組み合わせがトイレットペーパーホルダーの画像だったのか。

面積的に広い背景の方眼用紙が邪魔なのかな。殆どの人間は、背景の方眼用紙は画像の主要部分では無いと判断するはずだ。

わかった。無地で撮ってみよう。次の画像で検索してみる。



なにやら水道配管やシャワーヘッドのような画像が良く一致する。こんどは白壁背景を選んできた様だ。水道配管にシャワーヘッドねえ... 似た形なのかな。

google 先生画像の各部分を文脈(もうちょっと言うとベクトルや相互の配置接続関係を要素として纏めた情報)に分解することまではできている様だ。複数の文脈をそれぞれをある程度満たす画像を見つけてくるのかな。

分解した文脈のうち、一つだけ非常に良く一致する画像を見つけるような仕掛けではなさそうだ。

余白あるいは背景の大きさも検索結果に影響するようだ。次の画像で検索するとやはり水道配管の画像が多く見つかる。画像の殆どは部品の状態になっている。



もう少し余白を広くすると鍵が見つかる。



google 先生に色々なことを聞くとたまに「captcha 認証をして」と言われる。あれはどうやって作っているのだろう?






最終更新日  2020.08.19 01:22:52
コメント(0) | コメントを書く
2020.08.13
カテゴリ:ソフト開発日誌
MO ドライブを HARD OFF で見つけて、手持ちの MO メディアをサルベージしてみた。ディレクトリが不思議な文字化けをする。次は化け方の例だ。DOS で扱いが難しいのでファイル名に入った空白は '_' で置き換え、コントロール・コード、使えない文字は置き換えている。

size  mon  day year  file-name
  7714  3  14  1993  G3FIL.ASM
  7735  3  14  1993  G3FIL.BAK
  7263  3  14  1993  G3FIL.JNK
  1247  3  14  1993  G3FIL.OBJ
  8688  3  15  1993  G3FIL2.ASM
  8688  3  15  1993  G3FIL2.BAK
  4749  3  15  1993  G3FIL2.OBJ
  1701  2  19  1993  GTII___O.OBJ duplicated extension
  4323  3  15  1993  GTII2__O.OBJ Under line = space
   131 11  14  1992  GTII2__T.TFA
     0  3  14  1993  GTR22.AAK bit error? B turns into A
     0  4   8  1993  GTR22.RRJ
  5140 11  10  1992  GTRFFIL.AAK
  2804 11  15  1992  GTRI.BAK
  2817  2  19  1993  GTRI.C
   223  1  27  1993  GTRI.EEE bit error?
  4918  1  27  1993  GTRI.EXE
    28  8  26  1992  GTRI__.EEE
  3682  4   7  1993  GTRI3.BAK
  3899  4   7  1993  GTRI3.C
   194  3  15  1993  NONAME.OBJ
  3084 12  13  1995  ROO.NNK missing T, J turns into N?
   919 12  12  2010  ROOT.ASM
    27 11  26  1992  ROOT0.PZR turns into Z
  9954 11  18  1992  ROOTT.EXE
   519 11  18  1992  ROOTT.OBJ
  1932 12  13  1995  ROOTT.TXT
   332 11  18  1992 'ROOTT__(dq).C' (dq) = '"'
     8  6  10  1992  TAMM___C.CFG
  2013  2  11  1993  TRIGON.BAK
  2017  2  11  1993  TRIGON.DOC
 13204  2  11  1993  TRIGON.LZH
    36  1   1  1970  TTRI.PR
  1427  3  15  2101  TTRI2.PF
  5272  3  12  1981  TTRIFLL.AS
   702 11  29  1992  WAYING.BAK
   702 11  29  1992  WAYING.C
 21112  2  19  1993  WAYING.EXE
  1452  2  19  1993  WAYING.OBJ
    28 11  29  1992  WAYING.PRJ
  4623 12  13  1995  ZOOTT.BAK

化け方かディレクトリ構造を壊した場合は除いてある。
  • . .. が化けてディレクトリの親子関係が壊れた
  • ファイルサイズ部分が壊れて異様に大きくなったファイル(主に 10Mibyte 以上)は除いてある
  • ディレクトリエントリーのクラスタ番号部分が壊れて子ディレクトリにたどり着けなくなった
気づいた化け方の傾向は次の様になった。
  • 1 ~ 3 bit 程化けている
  • ファイル名の文字が重複する
訂正しきれず、数ビットの 0/1 が反転するのは理解できる。重複(厳密に言えば隣接するバイトで上書きされてしまう)が起きるのはなぜなんだろう。誤り訂正符号の理論をよく勉強すればもう少し背景が分かってくるのかも。

それとも Linux の FAT file system driver が壊れたディレクトリに弱く、意図しない memcpy, memmove などをしてしまうのだろうか?

ディレクトリ化けで永久にソースは失われた? 化ける前のファイル名を推測して、現役のハードディスクを探してみる。別の系譜で子孫が生き残っていた。






最終更新日  2020.08.13 01:14:08
コメント(0) | コメントを書く
2020.07.26
カテゴリ:ソフト開発日誌
ハードオフでジャンク 640MByte MO drive OLYMPUS MO643U5 を買う、110 円でジャンク box に入っていた。



そう言えば、手持ちの MO メディアは読めるのだろうか?一応、SCSI 接続のドライブは持っている。「予備になるかもしれない」機材が 110 円なら良いかな。

足が取れているなぁ。後で代わりの足を貼り付けるか。ん?もしかして一度開けた?足が貼ってあった部分がシールになっている。綺麗に貼り戻したのかな?



あっ、そうだ。MO メディアを見たことが無い人がいるかもなぁ。手持ちの 640Mbyte メディアを出しておこう。虹色に輝いている円盤を格納した四角いケースが MO メディアだ。



この大きさで 640Mbyte を格納する。比較のため右上に 32Gbyte の Micro SD card を置いておいた。簡単に諸元を比較してみる。いずれも実測値、Micro SD の容量はメーカー品種によって違う。大きさは見ての通り、重さは比較していない。

項目640M MO32G Micro SDSD / MO
容量
(bytes)
635,600,89631,914,983,424約 50.21
sequential read
転送速度
(Mbytes/sec)
2.0192.1約 45.8

テクノロジーの進化は驚異的だな。640Mbyte MO メディア 1 枚で 2,000 ~ 3,000 円くらいだったか。ドライブが 20,000 ~ 40,000 円くらいした。MO が普及していた頃に USB は無く、さらに SCSI Interface, cable, terminator も必要だった。SCSI 部分で 10,000 ~ 20,000 円くらいかな。

今時 Micro SD card reader はメーカー製パソコンなら普通に付いているし、スマホに標準装備されている。無くても 100 円ショップで探せば 100 円で売っている。

外観的な不具合は EJECT ボタンが引っ込んでいること、カラカラ音がすること(ネジが取れていた)、汚れがついていること。



あー、AC アダプタで給電が必要か。調べてみると EIAJ 極性統一プラグ(RC5320A) 区分 2 で 5V 1.6A だ。適当な変換ケーブルを付けて供給しよう。



ネジは 2 個の後ろ足の下にあるシールを剥がすと出てくる(自分が手にしたドライブは 1 個足が無い)。シール下からカラカラと音がしていた。ネジが外れた状態になったのは何でだろう。



ポストが割れていた。これでネジが締まらなかったのか。反対側はポストの形が残っていた。良く見るとヒビが入っていて、手で軽く強度を確かめたら、崩れてしまった。



丁寧にポスト再建?いずれパテとか使うのも慣れないとなぁ。ダサく養生テープで「仮止め」という恒久処置をして使うか。そのうちベタつくかカラカラに乾いて剥がれるかもしれない。

ドライブに皮脂が付いているなぁ。やっぱり開けたのか。ハードオフ・ジャンクなのだ。普通にあること。ドライブは OLYMPUS MOS3393E で 2002 年 8 月製だと読める。製造から 17 年 11 ヶ月経過している。皮脂をパーツクリーナーで拭き取る。



レーザー・ダイオードが劣化していることも考えられる。今後、書き込みで使う事は無いからレーザー強度は弱くなっていても平気かな。

透明スモークパーツのポストの一部が割れて動く様になっていた。



ボタンの支えも折れていた。スモーク・パーツとボタンの支えは接着剤で補強することにした。瞬間接着剤を使って見たけれど、ダメなんだよなぁ。盛れる接着剤の方が上手くいく。



内部を補修して、養生テープでケースを留める。緑のアクセントがダサダサ・デザインだな。ダイソーで買った汎用の足も取り付けた。結局付けた足も余り役に立たない状況だったのが後で判る。

手持ちにあった EIAJ 極性統一 DC プラグ区分 2 で電源供給ケーブルを作る。EIAJ 極性統一 DC プラグって RC5320A と言う規格名が付いているのか...



電源 ON、Windows10 PC に接続する。アクセスランプが点いてディレクトリを読み込んだ。おお、Windows10 はまだ MO に対応しているのか。



あれ?なんか変だな。MO メディアによって読める・読めないがある。読んだ内容も部分的に壊れている。なんか変な壊れ方だなぁ。

MO メディアによってはドライブの挿入側を下にして読めるようになった。ハードオフ・ジャンク、この程度は中難度だ。



データの壊れ方が... ECC による訂正限界を超えたのか。手持ちのドライブも動かしてみる。さらに問題が悪化した。機会が有れば別の日記に書くか。

ディスク表面はホコリで汚れているし、拭き取ると砂埃でキズが付いてしまった。俗な環境と使い方だと 25 年持たないのか。






最終更新日  2020.07.27 09:00:54
コメント(0) | コメントを書く
2020.07.18
カテゴリ:ソフト開発日誌
SMR HDD WD60EZAZ を買った直後に近い状態にするには、trim (Linux の command line で blkdiscard) を使う。あるいは mount option に discard を付ける。具体的には blkdiscard command を次の様にして使うと、HDD の全領域が trim される。

# blkdiscard -v -p 16MiB /dev/sdX

blkdiscard は ubuntu 16.04 以降で使える。util-linux package に入っているので、標準的なインストール構成なら使える状態になっているはず。

-v は進捗表示をする指定、-p オプションで指定している値は trim (SCSI なら unmap) command 1 回につき、何 byte 分を実施するかと言う値だ。16MiB は 16Mibyte 刻みで trim を発行する指定になる。理想は SMR HDD の allocation unit の整数倍にするのが良いと考えられる。外部からは分からないので、1Mibyte ~ 32Mibyte 程度の間で良いと思う。小さくしても、許容できる実行時間で済むと思われる。blkdiscard 実行例: 対象 /dev/sdc WD60EZAZ, -p 16MiB, 実行時間約 214 秒(経過出力 1 行で 1 秒)

/dev/sdX は trim しようとする HDD のノードだ。よく調べて指定して欲しい。WD60EZAZ の場合、trim すると block から読み出したデータは 0x00 の連続となる。実質的に消去になる。firm ware に直接 command を送って(送る手段があったとして) trim を取り消すなどの操作をしないと、データは復活しない。

普段使いならば、mount option に次の様に discard を指定するのが良いだろう。/etc/fstab にも同様に記述できる。

# mount -o discard /dev/sdXI /mount/point

linux kernel 5.4.47 で file system が discard に対応しているか簡単に検索してみると btrfs, ext4, f2fs, fat(exfat), gfs2, jfs, nilfs2, xfs が対応している。主要な file system は入っている。種類が少ないので惜しいと思う人もいるかも。

SMR HDD WD60EZAZ の trim command (discard あるいは unmap) の挙動は興味深い。色々と試した結果を書いていく。HDD の状態は前の日記でテストをした後の状態だ。ramdom read/write - sequential read x 1 - sequential {write and read} x 2 をした後だ。各操作の途中ディスク容量に対して 2 ~ 3% 程度のお試し read/write をしている。

この状態で trim (blkdiscard) を全領域に対して、分割無しに実行してみた。blkdiscard command に device の node を指定するだけだ。

# blkdiscard -v /dev/sdc
/dev/sdc: Discarded 6001175126016 bytes from the offset 0

5 秒も経たないうちに blkdicard は終了する。ちゃんと trim しているの?

多分 HDD の firm ware が back ground で処理しているのだろう。ほぼ 3 時間待って、sequential read の転送速度を測ってみた。グラフの縦軸は転送速度、横軸は進捗 0%: LBA=0, 100%: LBA=Last LBA だ。あれ?外周部分、分割構造境界だけ trim されている。trim された場所は平均で 400Mbytes/sec 出ている。



3 時間放置ている。frim ware が動作時間の 100% を使って trim 処理を実行していたら、平均転送速度 150Mbytes/sec として、 150Mbytes/sec x (3600 x 3sec) = 1,620,000 Mbytes の範囲、割合に換算して 27% は trim された状態になっていると期待していた。綺麗に 0x00 で wipe するまでもなく、allocation unit に trim された範囲を追記するなら、もっと早いはず。

当面の書き込み需要に応じるなら、trim する範囲は 10% 未満で十分というのも分かる。何だかなぁ。転送速度プロットの様にモヤモヤする。

(2回目) 同じ blkdiscard command を実行して、6 時間ほど放置する。sequential read の転送速度を測る。16 ~ 17% くらいが trim された様だ。



重ねて blkdiscard を実行すると、前の trim が取り消しになるのか、それとも 3 時間で 8% が back ground で trim されるのか。

(3 回目) 同じ blkdiscard command を実行して、12.5 時間ほど放置する。sequential read の転送速度を測る。24 ~ 25% くらいが trim された様だ。



一括の trim (blkdiscard) では直ぐに trim されないことは確かだ。転送速度が 400Mbytes/sec 出ていないところを狙って dd で読んでみると書き込んだデータが読める。

そこを狙って trim するとデータは 0x00 になり dd の転送速度は上がった。

blkdiscard 範囲を分割する指定 -p を付けて実行してみる。次に示す command line の太字部分のような指定だ。指定する値をいくつか試してみた。実行終了までに時間が掛かる。手応えがある。次の例のように 512Kibytes 分割だと見込みで約 4500 秒かかる。途中 ctrl-c で停止した。

# blkdiscard -v -o $(( 0 )) \
-l $(( 6001175126016 )) -p $(( 512 * 1024 )) /dev/sdc

-p に 512Mibyte を指定すると、23 秒で終了する。HDD の中で何か変化していると期待できる。

全領域で sequential read の転送速度は 400Mbytes/sec 前後出る様になった。転送速度のブレが大きく、買ったばかりと違っている



trim command の動作は allocation unit に trim 範囲を追記するだけのようだ。read/write command に対して allocation unit を通しで読んでみて trim された記録が見つかったら、範囲を記憶し、trim 済みか判断する。次の read/write command に対して、trim された領域なのか、いくつか記憶した trim 範囲と照合してみて最適な動作を決める様だ。

trim された後の sequential write の転送速度を測ってみる。CMR HDD に近い転送速度の傾向を示した。最外周で 200Mbytes/sec、最内周で 80Mbytes/sec 出ている。



分割構造の特徴は見えにくくなっている。相変わらず中央の分割の後半で転送速度 130Mbytes/sec で底打ちする。謎なままだ。

WD60EZAZ は都度細かく trim する使い方で性能が出る見込みがある。OS の file system に trim 指定を(Linux ならば discard 指定を)するか、自動で trim を積極的に使う環境ならば、CMR HDD に少し劣る程度の性能で使えるかもしれない。(注: ここで行った random read/write のテストは trim を使っていない)

より具体的には大規模ソースの build 作業で生成される object file の様に create - write - read - remove の繰り返しならば、障害を引き起こしそうなアクセス速度の低下や応答時間の長期化は経験せずに済むと思われる。それでも CMR HDD とほぼ同等は無理そう。

trim をせずに defrag したり、record file / data base の様にファイルの一部を read/write する使い方を続けたり、trim に対応しない RAID 構成で使うと、障害になるほどのアクセス速度の低下や応答時間の長期化が発生する可能性も分かった。

SMR HDD WD60EZAZ の性質が分かってきた。この HDD を買った目的は何だっけ? えーっと、バックアップ作業用に買ったはず。うん、バックアップを数分で消す blkdiscard の魔法を覚えた!

SMR 記録の HDD WD60EZAZ ランダムアクセステスト結果
SMR HDD random read/write アクセス後の sequential read/write 速度






最終更新日  2020.07.18 01:41:56
コメント(0) | コメントを書く
2020.07.15
カテゴリ:ソフト開発日誌
まず買ったばかりの SMR HDD WD60EZAZ の sequential read 速度を見てみる。縦軸は転送速度 bytes/sec, 横軸は 進捗で 0% が LBA=0, 100% が LBA=Last LBA だ。380Mbytes/sec 出ている。データシート上の最大転送速度は 180Mbytes/sec だ。



実用上この速度は出ない。Trim された領域を read して出ている速度だ。File System を構成するならば、書き込んだことが無い領域を読むことは無い。読んだとしてクラスタ単位で操作する都合上で行われるはずだ。380Mbytes/sec は記憶媒体に律速されない AHCI SATA I/F - WD60EZAZ 間の最大転送速度を示していると考えられる。

Trim されているので何回 sequential read を繰り返してもほぼ同じ結果になると考えていた。繰り返してみると、転送速度に僅かな変動が見られたり、



瞬間的に(全容量に対して 2 ~ 3% 程度の範囲で)突如として転送速度が低下する現象がみられた。なぜ起きるのか良く分かっていない。



買ったばかりなのに媒体上に不安定な領域でもあるのだろうか?あるいは、HDD の firm ware に使われているアルゴリズムが動作履歴に左右されやすい時間オーダーになっているのだろうか?

先に行った random read/writeに続けて、sequential read/write をする。1 回目の sequential read は転送速度が進捗に対して 3 段階で変化した。各段階で最大転送速度と最小転送速度の差が大きい。比較的早い外周領域(0% ~ 33.3%)の範囲でも 90Mbytes/sec 差が有り、ほぼ 2 倍の振れ幅がある。振れ幅も密度に差が有り、allocation unit に沿うように転送速度が低下している様に見える。



段階の位置を見るとほぼ進捗の 33.3%, 66.6% の所で段ができている。いかにも意図的な位置だ。大規模な分割構造がある様に見える。LBA で綺麗に 3 分割されているということは、媒体上では外周では細い環、内周では太い環に分割されているのだろうか? さらに細かく分割して最適化を追求するよりは動作検証をしやすくした様に見える。

1 回目のsequential write の転送速度(リンク先は続く sequential read を含む)を見てみる。「これは HDD なのか?」転送速度が波打つ様に変化した。分割構造の境界付近では最高転送速度は 200Mbytes/sec を越える。それ以外では IDE I/F 時代の HDD 程度の速度になった。外周部分で 30M ~ 70M bytes/sec だ。ULTRA ATA 33 ~ 100 が全盛で容量 20Gbyte ~ 100Gbyte の HDD がよく使われた時代に戻った感じだ。



転送速度の変化も分割構造の前後で非対称だ。ヘッドを静定する時間がシーク方向に依存しているか、HDD 媒体上の allocation unit に未使用追記領域が無かった場合の空き検索アルゴリズムに方向性があるのか?

特定条件を満たしたときにデーターシートスペック 180Mbyte/sec を出しているようにも見える。何が何でもスペックを出すような構造を設計した?

分割構造の境界付近を「SMR 追記を早く行うための余剰領域」かつ「不良ブロックが発生した場合に代替利用する領域」にしているのだろうか?転送速度が速くなる進捗の幅が 3%, 5%, 5%, 3% となるので、何か意図的な割り振りを感じる。

おおよそ HDD に書き込んだデータのうち、15 ~ 20% 位が書き換えられると想定して、追記未使用領域を用意しているのだろうか?あるいは運用中に不良ブロックが発生したとして、最大 20% 程の代替領域があれば、運用継続可能と想定している?

そうだとすると SMR 方式は物理的な記録密度向上に対して、性能と耐不良ブロックのために払う代償も大きい。コスト競争が激しい製品で、差し引き 3 割り増しにもなれば大きいのも確かだ。

全領域を Sequential write すればスッキリするのだろうか? sequential read 転送速度が向上し、CMR 方式 HDD と同等と見なせる程度に転送速度のブレは減るのだろうか?

2 回目の sequential read をしてみる。転送速度は全般的に向上した。分割構造の外周部で、205Mbytes/sec が出る様になった。転送速度のブレは依然として大きい。最外周の分割部分で転送速度の振れ幅は 70Mbytes/sec 程度、速度低下の機会はある程度減ったように見える。



中央、内周分割部分でも転送速度は 10M ~ 20Mbytes/sec 向上している。気持ち速度低下頻度が下がったように見える。

HDD 内の allocation unit をほぼカバーするような sequential write を行った積もりだった。write() システムコールに対して転送長 256Mibyte、Linux Kernel の BIO から AHCI driver 間の最大転送長は 30720kiByte (30Mibyte) にしている。HDD 上の allocation unit を綺麗に上書きで書き直せると期待していた。sequential read 転送速度の結果を見ると、依然として allocation unit に対して追記、溢れた場合は隣接 allocation unit に対する追記に振り替えている様に見える。

2 回目の sequential write をしてみる。転送速度が波打つ様なことは無くなった。最外周の分割構造で、upper 205M ~ 200Mbytes/sec, lower 160M ~ 155Mbytes/sec の転送速度が出ている。ある程度 block 配置状態が整理された様に見える。依然として、転送速度に振れ幅がある。



奇妙なことに真ん中の分割構造で、転送速度の下限が 130Mbytes/sec 程に安定して底打ちする現象が見られた。原因は分からず。勘ぐった見方をすると転送速度調整をしている様に見える。外周側の分割構造でも、転送速度の変化が進捗に対して 5Mbytes/sec になっている。HDD に乗ったチップ内の DMA controller 速度を媒体記録密度とは別の調整パターンで設定している?マーケティング / ブランディングと言った大人の事情?

3 回目の sequential read をしてみる。2 回目と比べて大きな変化は無い。分割構造の境界付近で転送速度が妙に遅くなったり、早くなるようなパターンは依然として残る。媒体上の場所毎に使い方が違うことを示唆している。



WD60EZAZ は Trim command を受け付ける。何か変化があるから command として受け付けるのだろう。試してみるか。

2020.7.15 22:50 追記: 手順の流れを明確化した。

2020.7.18 追記:
SMR 記録の HDD WD60EZAZ ランダムアクセステスト結果
SMR HDD WD60EZAZ 買った直後に近い状態に戻す - trim(blkdiscard) を使う






最終更新日  2020.07.18 01:38:29
コメント(0) | コメントを書く
2020.07.02
カテゴリ:ソフト開発日誌
Linux の Userland で cache flush をしたくなったので、x86/x86-64 アーキテクチャ上で cache flush 関数を実装してみる。Linux kernel 内に有った実装をほぼそのまま持ってくる。
#include <stdint.h>
static void clflush(volatile void *p)
{
  asm volatile("clflush %0" : "+m"(*(volatile uint8_t *)p));
}
clflush ソース

kernel から持ってきた理由は、検索をしていたらcacheflush() system call が見つかったからだ。kernel source を調べてみると x86/x86-64 アーキテクチャではこの system call は無い様に見える。

特権を持っていなくても、CLFLUSH 命令は使えるからだろう。

試しに使ってみるコードを実装する。

#include <stdint.h>
#include <stdio.h>
#include <string.h>

static void clflush(volatile void *p)
{
  asm volatile("clflush %0" : "+m"(*(volatile uint8_t *)p));
}

const char hello[] = "Hello world.\n";

void MainB(char *buf)
{
  memcpy(buf, hello, sizeof(hello));
  clflush(buf);
  fputs(buf, stdout);
}

int main(int argc, char **argv, char **env)
{ char buf[128];
  MainB(buf);
  return 0;
}
clflush テストコード全体

逆アセンブルしてみる。まぁ、まぁ、綺麗に inline でオブジェクトコードが生成されていた。

0000000000400620 <MainB>:
  400620: 48 b8 48 65 6c 6c 6f movabs $0x6f77206f6c6c6548,%rax
  400627: 20 77 6f 
  40062a: c7 47 08 72 6c 64 2e movl   $0x2e646c72,0x8(%rdi)
  400631: 48 89 07             mov    %rax,(%rdi)
  400634: b8 0a 00 00 00       mov    $0xa,%eax
  400639: 66 89 47 0c          mov    %ax,0xc(%rdi)
  40063d: 0f ae 3f             clflush (%rdi)
  400640: 48 8b 35 09 0a 20 00 mov    0x200a09(%rip),%rsi        # 601050 <stdout@@GLIBC_2.2.5>
  400647: e9 74 fe ff ff       jmpq   4004c0 <fputs@plt>
  40064c: 0f 1f 40 00          nopl   0x0(%rax)
より良い使い方は、前後にmemory barrierを使う。

cache line size も /proc/cpuinfo から拾わないと。
clflush size    : 64
cache_alignment : 64






最終更新日  2020.07.02 22:40:13
コメント(0) | コメントを書く
2020.06.28
カテゴリ:ソフト開発日誌
SMR 記録の HDD WD60EZAZ を Linux で使うには BIO (Block IO request) のタイムアウト設定 /sys/block/block_device_name/queue/io_timeout に 240000 (240秒) を設定すれば sync() でハングせずに使えそうなことが分かってきた。設定値は kernel が管理する cache 量、稼働中に想定される単位時間当たりの書き込み量、頻度に依存すると思われる。主記憶サイズ 24Gibyte での値だ。

ランダムアクセステストの結果に気になる傾向があったので、記録に残しておく。

ランダムアクセスの分布は LBA: [0..MaxLBA] = a*random(), Length: [4096..512Mibytes] = exp(l * random()) bytes となる様に a, l を定めている。read, write はほぼ半々になる様に混在させている。

ランダムアクセステストをする前に行った HDD アクセス履歴の概要を書く。最後の全 block 連続書き込みから、次の表の様にランダムアクセスをした状態だ。6Tbyte に対して、221266 回 write のランダムアクセスをしている。

テスト前のランダムアクセス数
Read / Write回数
Read220113
Write221266

テスト後のランダムアクセス数
Read / Write回数
Read269244
Write270439

均等に分散しているアクセスだと仮定すると 6Tbyte / 221266 ≒ ‭27,121,994 (27Mbyte) 程度の範囲に 1 箇所はランダムアクセスをして乱れがあるはずだ。厳密にはアクセス長分布は 512Mibyte まで有るので、27Mbyte 丸々上書きされている場合もある。意外と疎な感もある。

OS の Cache を使わずに Read/Write Random Access をした結果から、Read のアクセス時間と転送長の関係をプロットしたグラフを見てみる。最小 Read Turn Around Time は約 8ms だった。Seek time + Rotation 待ち時間として考えられる。気になるのは、アクセス時間の分布がいくつかの帯に分かれることだ。



構造を示すような資料は見つからなかったので推測で書く。HDD の記録面は
  • 4Mbyte 程の CMR Allocation Unit
  • 10M ~ 30M byte 程度の単位で管理された Small SMR Allocation Unit
  • 200M ~ 300Mbyte 程度の単位で管理された Large SMR Allocation Unit (Small SMR Allocation Unit をまとめたか、あるいはさらに高密度記録を行っている)
といった階層的な構造になっている様に見える。シーケンシャルアクセステストの結果から、ドライブ全体を 3 分割する構造も見えている。

SMR HDD らしい所は転送長が 1Mbyte 未満の所で、Access Time が 8ms ~ 300ms 程度の幅があることだ。最小アクセス時間と最大アクセス時間の比は 37.5 倍になる。細かいアクセスが多発する場合、総アクセス時間の予測をしにくい。

Small SMR Allocation Unit も Large SMR Allocation Unit も追記を行っていく構造になっていると思われる。2020.06.29 加筆 書き込みをした場合、LBA, (新しい書き込みだと印を付ける)SerialNumber, block data を組みで追記し、プラッタ上の LBA の並びは追記順になっている様に見える。SMR 記録された track を読んでいって、読みたい LBA の最新が見つかるまで、シーケンシャルにアクセスしていると推測する。

Write のアクセス時間と転送長の関係をプロットしたグラフを見てみる。条件は先ほどの Read 同様 OS の Cache は使わない。最小 Write Turn Around Time は 140us 程になっている。10Mbyte 程の書き込みまで多くの場合 転送速度は 400Mbyte/sec だ。SATA-III I/F の転送速度 6Gbps の上限に近い。プラッタに書き込まず、HDD 基板上の半導体メモリに格納したら、転送完了している様に見える。もし、電源断になったらどうするのだろう?



プラッタとスピンドルモーターでフライホイールを構成して、Flash Memory か特別な磁気媒体領域に書き込み終わるまで、電源供給無しに動作し続けるのだろうか?

実効的な HDD の cache size は 10Mbyte 程に見える。WD Blue Data Sheetには 256Mbyte と表記されているので 10Mbyte x n tansaction の様に使っているか、Small/Large SMR Allocation Unit の再構築に使っている可能性がある。

転送長に対して顕著にアクセス時間が長い場合が見られる。アクセス時間からして Small/Large SMR Allocation Unit を再構築しているのでは?と考えられる。追記ができなくなった場合、近隣の Allocation Unit に追記するか、それも出来なくなった場合は、再構築をするのだろう。このグラフからは読み取りにくい。HDD を休ませることなく連続してランダムアクセステストを実施していると、次の様なグラフに変化する。



分布がより鮮明に現れ、転送長が 512Mibyte の場合のアクセス時間は 7 ~ 10 秒だったのが、45 秒程に変化する。

連続してランダムアクセステストを実施していると、read もアクセス時間が変化する。転送長が 1Mbyte 以下で 8ms でアクセス完了する場合が減る。Small SMR allocation Unit から読んでいると思われる 300ms 程のアクセス時間になる。転送長が 1Mbyte 以上の場合も、Large SMR Allocation Unit を 2 つ跨ぐ様なアクセス時間に変化している。対数グラフで一マス上なので体感的に速度は 1/5 ~ 1/10 程度に下がってしまった様に感じるかも。



OS の cache を使った場合のアクセス時間と転送長の関係を見ていく、Read の方は、Queue に溜まった transaction が完了するまで待つ場合が出てくる。待つ場合は 100Mbyte/sec 出ている転送速度が 3Mbyte/sec 程度まで低下した様に見える。最大で 30 ~ 40 秒待つ場合が出てきている。アプリケーションによってはフリーズしたような体感になる。



連続アクセスを続けていると、待ち時間はさらに長くなる。200 秒ほどの待ちになる。先行する write transaction が完了するまでの待ちだと考えられる。これが、冒頭で触れた「タイムアウト設定 /sys/block/block_device_name/queue/io_timeout を 240000」にしようと考えた背景だ。



OS の cache を使った場合の write は、順調に OS の cache に格納して完了している。



転送速度が 2Gbytes/sec と 3Gbytes/sec に別れる原因は探っていない。OS の cache 管理構造が原因なのか、主記憶が 24Gibyte なので Memory Bus の channel 構成が非対称なのが原因なのか。

ランダムアクセスですっかり遅くなってしまった SMR HDD WD60EZAZ のアクセス速度を回復する方法は有るのだろうか?

2020.7.16 追記: SMR HDD random read/write アクセス後の sequential read/write 速度
2020.7.18 追記: SMR HDD WD60EZAZ 買った直後に近い状態に戻す - trim(blkdiscard) を使う

2020.7.18 追記: Android, Linux Kernel の様な大規模ソースを格納して build 作業に使う場合、mount option discard (trim) を付ければ hang up に近いような応答時間にならずに済むかもしれないことが分かった。それでも、ランダムアクセスは性能的に不利だ。積極的には build 作業に使わない方が良さそう。






最終更新日  2020.07.18 01:30:33
コメント(2) | コメントを書く

全880件 (880件中 1-10件目)

1 2 3 4 5 6 ... 88 >


© Rakuten Group, Inc.