センニジュウヨン

意味なんてない

C++においてメモリブロックのオーバーラップ判定は不可能なのか

先日 std::memcpy を使うコードを書いた。

void* memcpy( void* dest, const void* src, std::size_t count );

memcpy は src から dest へ count バイトだけコピーする簡単な関数だが、いくつか注意点があり、 その一つが、メモリの範囲がオーバーラップしていると動作が未定義という点である。

この点が気になったので assert でも書いておこうと思ったのだが*1、 ポインタ演算について調べてみると、どうもこれは(C++の規格の範囲内では)書けないんじゃないかと思い始めたりして、 色々迷走したのでそれについて調査過程を含めてここに記録しておく。

(規格文書を直接あたったわけでもない調査なので間違ったことを書いているかもしれません。ツッコミ歓迎。)

そのオーバーラップ判定大丈夫?

オーバーラップ判定コードは以下のようなものである。

// オーバーラップしていないかどうかチェック
assert(((src+count) <= dest) || (src >= dest+count));

自分で考えて判定を書くと、もっとグチャッとした処理を書きそうだったので、ググってどう書くべきか調べた。 その結果、 Linus のメールに書いてあるものがシンプルで良さそうだったのでこれを参考にした。 件のメールでは unsigned long にキャストしていて、念の為 unsigned long のオーバーフローにも配慮する場合も示してあるが、 オーバーフローのチェックとかほんとに要るのか疑問だったので、ポインタ同士の演算について調べてみることにした。

ポインタへの加算は大丈夫そう

ポインタへの加算については、cppreference の算術演算子のページ*2に記載があり、 配列の最後の要素+1までは保証されるけど、それを超えると未定義動作になると書いてある*3。 今回の事例は配列の末尾を超えることは無いものだったので、とりあえずこれは大丈夫だと分かった。

問題はポインタ同士の比較

ポインタ同士の比較については、cppreference の比較演算子のページに記載があり、 内容が多いのだが、関係しそうな部分だけ抜粋する。

2つのオブジェクトへのポインタ (の変換後) の比較の結果は、以下のように定義されます。

  1. 2つのポインタが同じ配列の異なる要素を指している場合、または同じ配列の異なる要素内の部分オブジェクトを指している場合、大きい添字を持つ要素を指しているポインタの方が他方より大きいとみなされます。 別の言い方をすると、ポインタの比較の結果は、それらが指している要素のインデックスを比較した結果と同じになります。
  2. 片方のポインタが配列の要素を指すか配列の要素の部分オブジェクトを指し、他方のポインタがその配列の最後の要素の次の要素を指す場合、後者のポインタの方が前者より大きいとみなされます。 単一のオブジェクトを指しているポインタは、サイズ1の配列を指しているとみなされます。 つまり &obj+1 は &obj より大きいとみなされます。 (C++17およびそれ以降)
  3. union でないクラス型のオブジェクト内で、2つのポインタが同じメンバアクセスを持つ異なる非静的データメンバを指している場合、またはそのようなメンバの部分オブジェクトまたは配列要素を指している場合、後に宣言されたメンバを指しているポインタの方が他方より大きいとみなされます。 別の言い方をすると、同じメンバアクセスモードを持つクラスメンバは、宣言された順番でメモリ内に配置されます。

(途中省略)

2つのポインタが、より大きいとも等しいとも規定されていない場合、比較の結果は未規定です。結果は非決定的であってもよく、プログラムの同じ実行における同じ被演算子を持つ同じ式の複数回の評価に対してであっても、一貫している必要はありません。

ここで、1 は同一配列内の要素での前後関係について、2 は配列内のものとその配列の最後の次の要素との前後関係について、3 はクラス内での前後関係について言及している。 重要なのは、同一ではない配列の比較について一切言及していないことである。 そして引用の最後の方にあるように、言及がないということは比較結果は未規定であることを意味する。

前述のオーバーラップチェックコードでは、同一配列内のポインタ同士(オーバーラップの可能性がある)では正しく動くだろうが、 別の配列同士(これは普通オーバーラップしない)では正しく動く保証がない。\(^o^)/オワタ

(非決定的でもよいという文言も気になる。はじめは、これがポインタ比較全般についての言及かと思ったが、引用先のページの作りからして未規定動作時のみへの言及だと思われる*4。 未規定動作時には既に正しく動く保証がないのでここは突っ込んで考える意味は余りなさそう。)

解決策?

なんとかならないか模索していたら、Stack Overflow のある回答が目についた。 要は、ポインタ比較がだめなら intptr_t で比較すればいいじゃない、という内容。 たしかに intptr_t 同士の比較では未規定とか未定義動作ということはありえないように思える。

前述のオーバーラップチェックコードの場合は特に signed である必要もないので、やるとしたら uintptr_t を使うだろうか。 ただ気になるのは、reinterpret_cast<uintptr_t>(...) という形でキャストが必要になるのが何となく不安になる*5のと、 uintptr_t での比較がポインタでの比較で意図していたものと同じ意味になるという保証があるのかという点。

詳しくは規格を見るのが正しいんだろうけど、そんな気力もないのでまたもやググって cpprefjp の uintptr_t のページに以下のような記述を見つけた。

この型を実装するかどうかは処理系定義。

この型は、以下の動作が保証される:

  1. 有効なvoidへのポインタからuintptr_t型への変換
  2. uintptr_t型のポインタ値からvoidへのポインタへの逆変換
  3. 変換前と逆変換のポインタ値が等値となる

実装するかどうかは処理系定義とあるが、今回は定義してある環境しか相手にしないのでとりあえず置いておく。

そして気になるのが、保証される動作が極端に少ないこと。変換と逆変換が正しくできてポインタ値が同じになるとしか書いていない。これを見る限り、規格内で意味のある比較は無理筋に思える。

真の解決策

というわけで、「無理っぽいです」という記事を書こうとしたわけだが、改めてググってみたら正解らしきものを見つけた。(なぜあのとき見つからなかったのか…)

Stack Overflow のある回答に以下のように書いてある。

int overlap_p(void *a, void *b, size_t n)
{
    char *x = a, *y =  b;
    for (i=0; i<n; i++) if (a+i==b || b+i==a) return 1;
    return 0;
}

要は比較は比較でも等値比較を使えってことである。

上の方でポインタの比較について引用したが、省略した部分に等値比較についての以下のような記述がある。

2つのポインタ (の変換後) の等値比較の結果は、以下のように定義されます。

  1. ポインタがどちらも NULL ポインタの場合、それらは等しいとみなされます。
  2. ポインタが関数ポインタで、同じ関数を指している場合、それらは等しいみなされます。
  3. ポインタがオブジェクトポインタで、同じアドレスを表している場合、それらは等しいとみなされます (これには、同じ共用体の非静的メンバを指している2つのポインタや、標準レイアウト構造体を指しているポインタとその最初のメンバを指しているポインタや、 reinterpret_cast によって関連付けられているポインタなどが含まれます)。
  4. それ以外のすべてのポインタは等しくないとみなされます。

今回の場合は 3 に当てはまりそうなので未規定ではなくなる。 これにて解決!

(でもなんか冗長っぽく見えて釈然としない。標準ライブラリとかコンパイラの組み込み関数とかでサクッと判定できないものか)

*1:結局、当該コードはオーバーラップして使われることがないと判断し、実際には assert は書かなかった

*2:日本語版はアレな機械翻訳なので英語版へリンク

*3:配列有効範囲外を指すポインタ値は存在が許されない - yohhoyの日記も参照されたし

*4:ほんとのところは規格を見てみないとわからないけど

*5:reinterpret_cast ってなんとなく不安になりますよね?

Synology DS418play のベンチマーク

先日買った NAS、 DS418play のベンチマークを取ってみた。

購入記事はこちら 1024.hateblo.jp

ベンチマークのやり方

ベンチマークソフトはちょっと探してみたが、NAS用に良さげなものを見つけられなかったので 汎用的に使える CrystalDiskMark(以下、CDM) を使って計測してみた。 最新版の 6.0.0 x64 で、なんとなく UWP 版を入れてみた。

CDM で何度か適当に測ってみると、シーケンシャルアクセスはほぼ一定だが、ランダムアクセス性能が実行のたびに結構変わることがわかった。

ベンチマーク結果1ベンチマーク結果2
ランダムライトが特に異なる結果

また、テストサイズの大小でも結果が変わってくる。さらに、テストサイズを大きくしていると、時間とともに徐々に結果が良くなっていった。

CDM のデフォルトの設定だけでは安定した結果を得られないことが分かったため、ベンチマークのやり方を以下のように決めた。

  • テストサイズは最大の 32GiB と、最小の 50MiB の2種類を指定
  • テスト回数は最大の 9 を指定
  • 同一条件で 5 回(サイズが小さいときは2回)テストし、すべての値の最大値を求める

テスト回数については、9 回でもまだバラツキがあったので、それをさらに複数回やることにした。 テストサイズが小さいときはバラツキも少ないようなので2回だけにした。 また、平均値ではなく最大値にするのは、CDM の計測方法でそもそも最大値を使っているようなので、それに合わせた。 平均や標準偏差も求めたほうが良いのかもしれないが、今回は面倒だからやっていない。

ベンチマーク対象

今回のベンチマークの趣旨の一つとして、Samba 共有の設定をどうするかを決める、というのがあり、 共有の設定を 3 種類用意してそれぞれに対してベンチマークを行った。

  • デフォルト設定
    • f:id:KiKibits:20180606213013p:plain:w215f:id:KiKibits:20180606213020p:plain:w215
      DSM6.2 で共有を設定する際の規定の設定
  • 圧縮を有効
    • f:id:KiKibits:20180606213353p:plain:w215f:id:KiKibits:20180606213358p:plain:w215
      デフォルト設定に圧縮のために必要な設定だけを足したもの
  • 暗号化を有効
    • f:id:KiKibits:20180606213759p:plain:w215f:id:KiKibits:20180606213803p:plain:w215
      デフォルト設定に暗号化のために必要な設定だけを足したもの

また、ベースとなるファイルシステムは Btrfs で、HDD を 2台接続した SHR(Synology Hybrid Raid) なので RAID-1 相当である*1。 HDD は NAS と同時に購入した 7200rpm のもの。

f:id:KiKibits:20180606235528p:plain:w400

圧縮は恐らく Btrfs の透過圧縮のものだと思われるが、調べていないので確証はない。 暗号化も具体的にどうやっているか調べてないのでわからない。

なお、リンクアグリゲーションや SMB マルチチャンネルは一切使わずに先日購入したスイッチ経由で 1000BASE-T 接続している*2

1024.hateblo.jp

SMBのバージョン(dialect) は 3.1.1(最新のはず)。 PowerShell(管理者) で以下のように確認できる。

PS C:\WINDOWS\system32> Get-SmbConnection

ServerName ShareName UserName   Credential Dialect NumOpens
---------- --------- --------   ---------- ------- --------
NASX       IPC$      PCX\userxx PCX\userxx 3.1.1   1

NAS の管理画面(DSM) では、デフォルトでは 3系 が無効になっていたので設定する必要があったはず。

ベンチマーク結果

デフォルト設定の結果圧縮設定の結果暗号化設定の結果
32GiB 9x5回 ベンチマーク結果 (※複数の結果を合成した嘘画像)

デフォルト設定の結果圧縮設定の結果暗号化設定の結果
50MiB 9x2 回ベンチマーク結果 (※複数の結果を合成した嘘画像)

シーケンシャルアクセスの性能はどれも大差なく、測定ごとのブレも少ないので見るべきはランダムアクセス性能である。

50MiB の方は、"暗号化" でランダムライト性能が落ちているの以外はほぼ同じ結果で、4KiB Q1T1 以外は 1000BASE-T の帯域を使い切っていると言って良さそう。

32GiB の方は、"暗号化" が相変わらずランダムライトで性能が落ちているが、ここにきて "圧縮" が "デフォルト" を上回ってきた*3。また、上記嘘画像では分からないが、"圧縮" だけは計測ごとのブレが少なく、かなり安定してこれに近い性能が出ていた。その点、"デフォルト" はブレが大きく、これより性能が落ちることが頻繁にあった*4

というわけで、今後は圧縮をメインに使うことにした。

ReadyNAS Ultra 4 でもやってみる

ついでに、同一のベンチマーク手法で旧 NASベンチマークを取ってみた。

こちらは HDD(5400rpmクラス) 4台構成の ext4 X-RAID2 であり、RAID-5 相当なので注意が必要。 f:id:KiKibits:20180606233730p:plain:w700 ネットワーク構成等は基本的に同じだが、SMB の dialect は 1.5 である。共有の設定に暗号化や圧縮はなかったと思う。

結果は以下

旧NASの結果
32GiB 9x5回ベンチマーク結果 (※複数の結果を合成した嘘画像)
旧NASの結果
50MiB 9x2 回ベンチマーク結果 (※複数の結果を合成した嘘画像)

シーケンシャル性能は 旧→新 でだいぶ上がったが、ランダム性能は及んでいない部分もあるということが分かった。 これが Btrfs のせいなのか、RAID-1 と RAID-5 の違いのせいなのかはわからないが、 旧NAS からのデータ移行が終わったら新NAS の方へ HDD を移植するつもりなので、 気が向いたらまた計測するかも。

*1:RAID-1 だと、1台の場合とさほど変わらないか遅くなると思うが、読み込みは速くなる場合もあるらしい

*2:そもそもこのスイッチではリンクアグリゲーション使えない気がするし、使えても単一接続では効果ない気がする

*3:ランダムリードは若干落ちているが…

*4:"暗号化" のブレは中間くらいだが、そもそも性能が微妙

Synology の NAS DS418play を購入

今まで使っていた NAS が手狭になったわけではないが、勢い余って新しい NAS を購入。 旧 NAS のほうで、時々ファイルのコピーに失敗する現象が出ていた *1 のも一因(再試行すれば問題ない)。

買ったのは Synology DS418playAmazon にて ¥49,130(税込) で購入。

NAS は NETGEAR 製のものだが、それ以外のメーカーのものに手を出してみようと思い、 軽く調べた感じでは QNAP, Synology という台湾 の2メーカーが定番らしかった。

また、ファイルシステムとして Btrfs というのがあるらしく、せっかくなので対応したものを選ぼうとしたら、 QNAP の方が Btrfs をディスっていて若干引いた。 Synology は Btrfs に肯定的。NETGEAR は Btrfs を擁護というか、むしろ QNAP をディスっている↓

「Btrfsは低速」「パフォーマンスがすべて」と言い、従来のファイルシステムEXT4にしがみついているNASメーカーがあります。

ということで、平和な Synology 製にすることにした。

Synology のNASでは Btrfs はエントリークラスの製品では使えないらしく、 若干高めのものから対応しているようだった*2

今使っている Ready NAS と同じ4ベイタイプで、Btrfs が使えるもので、以下の2機種に絞った。

  • DS918+
  • DS418play

上位機種の DS918+ の方は若干CPUが良いもの使っていて、NVMe キャッシュが使えるなど、 その他にも細かい違いがあったが、 キャッシュの効果に懐疑的なのと、ストレージ以外の用途に積極的に使う気がないので 下位機種の DS418play にしてみた*3。 (ちなみに執筆時点の Amazon で 税込み ¥6,669 の価格差)

また、これはNASキットで、HDD は付いていないので、初期装備としてHDDを購入した。 HDD は自分の中で悪いイメージがついていないHGST*4NAS用のもので1TB単価が安いものを購入した。

買ったのは HGST 0S04005-2 (HDN726040ALE614 * 2) という 4TB 7200rpm のもの。 Amazon にて ¥28,942(税込) で購入。

最近は NAS の中身は 5400rpm のものにしていたが、こちらは 7200rpm のもの。 熱とか消費電力とか音とかが若干気になったが、NAS用を謳っているので気にしないことにする。

雑感

以下、軽く使ってみた感想とかメモとかを取り留めなく列挙。

本体軽い。ReadyNAS(旧NAS) は馬鹿みたいに重い。2.5kg くらい違うみたい。

HDD 繋がないと初期設定できなかった。

HDD をネジ無しで固定できるのは非常に良い。ReadyNAS はネジ固定。

HDD つないだら Btrfs, SHR に勝手になった。

初期設定時は余計なアプリ等は入れないようにした。後から入れられるし。

起動時のビープ音は、もうちょっと優しい感じにしてほしい。

ファンの音は結構静か。いくつかモードがあって、デフォルトで低ノイズモードだった。

HGST HDD のカリカリ音は結構うるさい方。

ソフトウェアのアップデート(DSM6.2) が出ていたのでアップデートした。デフォルトの設定等が変わっている可能性を考慮してボリューム等は一回消して作り直してみた。

ベンチマークとか本格的な使用感についてはまた今度。

*1:以前ググった感じだと、sambaのバージョンを上げれば直りそうだが、 ファームウェア更新が打ち止めになっているため、やるなら不具合覚悟の手動更新のため、面倒くさい

*2:購入後に知ったのだが、5月末にリリースされた DSM6.2 からは ARM 系の安いモデルでも Btrfs に対応するようになったらしい

*3:いろいろいじった今では上位の方にしてみても良かったかなと思っているが、今だけかも

*4:Seagate, WD は過去(といってもだいぶ前だが)に壊れた経験あり。今は HGST も WD の傘下らしいのだが、気持ちの問題

スイッチングハブを購入

手持ちのハブが手狭になったので新規購入した。 今まで 5ポートx2 構成だったところに 8ポート のものを追加。 これからは 8ポート をメインで使い、足りないときに古いもので補う形に。

以前のものも今回のものも、アンマネージド、メタル筐体、電源内蔵、ファンレス1000BASE-T 対応のもの。 それに加えて今回は50℃環境まで使えるものという条件を追加して、候補の中から安めのものを選択した。 10Gの可能性も探ってみたが、まだ高いしそもそも対応製品ひとつも持ってないのでやめておいた。

購入したのは ELECOM EHC-G08MN2-HJBAmazon にて ¥4,427(税込)。

メイン基板に電解コンデンサを使っていないとのこと(電源部分には使われているんだろう)。 それでも、50℃まで対応してるし、MTBF 78年だしそう悪くもなさそう。 そもそも家庭向けで MTBF 書いてあることが少ないのでちゃんと考えて作っている感はある。

それ以外の仕様は、EEE(IEEE 802.3az)対応(省電力機能)、ループ検出機能、あたりが使ってたものとの目立った違い。 EEEはよく知らないのだが、接続している機器が対応していなくても効くんだろうか。 効かない気がするが、対応機器あまり持ってなさそう。 ループ検出機能は使うことなさそう。

届いたものを開けてみて小ささに少し驚いた。 全体的なサイズ感では今まで使っていた 5ポート の一機種と同じくらいで(小さい方の機種には負けるが)、体積的にはむしろ小さい。

いまのところまずまず満足。

スイッチングハブの仕様の見方

以前購入した際にはテキトーに安いのを買っていたような気がするが、 改めていろいろ調べてスイッチングハブの仕様の見方をなんとなく把握したので雑多にメモ。

スイッチングファブリックとパケット転送能力を見れば規格の理論値を出す能力があるかどうかがわかる。 スイッチングファブリックは 1Gbps(1000BASE-T) * 2(全二重) * 8(ポート数) = 16Gbps 以上の能力があれば十分。 パケット転送能力は、1Gbps(1000BASE-T) / 672bit(最小フレーム+α) = 1488095.2381pps 以上の能力があれば十分。 ただし、これは 1ポートあたりなので、全体としては 1488095.2381pps * 8(ポート数) = 11904761.9048pps ≒ 11.9Mpps ということになる。 これらを満たせばワイヤースピード(ポート単位)だとかノンブロッキング(全体)だとか言えるらしい。 今回買ったものはこれらは満たしていた。2011年に購入した2機種は仕様表に記述がないものもあったが時期的には満たしてそう。 (2009年の記事で "現在のスイッチはほぼノンブロッキング" との記載がある)

その他に、レイテンシ等の要素もあるが、マイクロ秒レベルの話のようなので家庭用では関係なさそう(そもそも仕様表に載っていないことが多い)。 MACアドレス登録数も普通に4000とかあるので家庭用では関係なさそう。 ジャンボフレームも9000bytesかそれ以上に対応しているものばかりなので差別化にはならない(一部の機器だけ大きくしても無意味だし)。 AutoMDI/MDI-X、オートネゴシエーション、フロー制御(IEEE802.3x,バックプレッシャー)等は当然のように対応されている。 EAP,BPDU透過機能とかは昔の機種の仕様表には書いてないが、自分の用途では今後も必要とすることなさそう。

いろいろ調べてみたが、家庭でのカジュアルな使い方の場合、これらを気にする必要は一切なさそう。 最安値のものでも必要な機能が全部入っていて性能は最大になっている。 あえて最安値以外の製品を選ぶとしたら、寿命とか耐久性とか消費電力とかを値段とのバランスをみて考えるくらいしかない。

10G対応のものだと色々違ってくるんだろうが、10G高い。早く家庭用にも普及して安価になってほしい。

ReadyNAS Ultra 4 に HDD を追加した

2011年から使っている ReadyNAS Ultra 4 の空き容量が心許なくなったので HDD を追加した。 4台搭載可能なところ既に3台積んでいたので、今回で4台目。

NTT-X Store で Western Digital の WD30EZRZ-RT を購入。 3TB SATA3(6Gbps) 5400rpm キャッシュ64MB のもの。 会員向けクーポン込みで ¥7,980 で、購入時の価格.com の最安値よりも安く買えた。

ディスクの追加前に、念のためにファイルシステム整合性チェックとディスクスクラブを実行。 ファイルシステム整合性チェックは5分でエラーなく終了。 ディスクスクラブは10時間かかったのでディスクの追加は翌日になった。

ディスクの追加後、自動でボリュームの拡張が始まった。 ボリュームの拡張終了まで22時間弱かかった。 (使用可能領域 4,625GB中、4,437GB(95%) 使用している状態)

結果、使用可能領域が 4,625GB から 7,403GB へと 2,778GB 増えた。

3台構成から4台構成になったので、多少は速くなっていることを期待して速度計測をしてみた。

結果はほぼ変わらず。

before f:id:KiKibits:20170625084621p:plain

after f:id:KiKibits:20170625084745p:plain

Crystal Disk Mark で何度か測っていると、そのたびに数字がある程度変わる。 ディスク追加の前後での変化はその誤差の範囲内だった。

Anker PowerCore+ 10050 の充電状況をグラフ化

Z2 の新バッテリーの充電状況をグラフ化したのと同様に、PowerCore+ 10050 の充電状況もグラフ化してみた。

1024.hateblo.jp

使用機器
  • Anker PowerPort+ 6 (QC2.0対応、電源として)
  • Route-R RT-USBVAC3QC (QC2.0対応USB簡易電圧・電流チェッカー)
  • サンワサプライ USB3.0延長ケーブル 0.5m (電源からRT-USBVAC3QCへの接続用)
  • Volutz MicroUSBケーブル 1m (RT-USBVAC3QCからZ2への接続用)
  • Xperia X Performance (カメラでの記録用)

Z2 の時と違うのは電源として PowerPort+ を用いている部分。

実験方法

基本的には Z2 の時と同じ。

ただ、フル充電に4時間かかることが想定されるので、タイムラプス撮影の間隔を1分とした。 本当は2分にしたかったが、撮影に使った “TimeLapse Video” というアプリが無料版だと任意の時間間隔を 設定できないので、プリセットで最長の1分間隔とした。

また、今回は扇風機の風を当てていない。照明の関係でPS4の上で撮影したので、熱の部分では過酷な状況。

実験結果

f:id:KiKibits:20160817235521p:plain f:id:KiKibits:20160817235528p:plain

フル充電までにかかった時間は 4時間10分ほど。

考察

Z2 のときと比べて電流の変動が激しい。PowerPort+ が悪いのか PowerCore+ が悪いのかはよくわからない。 また、PowerPort+ には、撮影用の X Performance も接続していたので、それの影響もあるかもしれない。

最終的な電力量は 48.66Wh となった。PowerCore+ の容量が 36.18Wh なので、投入した 48.66Wh の 74% がスペック上の容量となる。Z2の時は 86~87% だったので、それよりはかなり低し数値になっている。これが電流の変動が激しかったせいなのかどうかはよくわからない。

Xperia Z2 新バッテリーの充電状況をグラフ化

Z2 のバッテリーを新しくしたので、新バッテリーの充電状況をチェックしてグラフにしてみた。

Z2 のバッテリー交換については、以下を参照
1024.hateblo.jp

使用機器
  • Anker PowerCore+ 10050 (モバイルバッテリー、電源として)
  • Route-R RT-USBVAC3QC (QC2.0対応USB簡易電圧・電流チェッカー)
  • サンワサプライ USB3.0延長ケーブル 0.5m (電源からRT-USBVAC3QCへの接続用)
  • Volutz MicroUSBケーブル 1m (RT-USBVAC3QCからZ2への接続用)
  • Xperia X Performance (カメラでの記録用)

Anker PowerCore+ 10050 の購入経緯については、以下を参照
1024.hateblo.jp

実験方法
  1. バッテリーを新しくしたZ2を一回フル充電・フル放電させる(電源が落ちた状態)
  2. フル充電のモバイルバッテリーと電圧・電流チェッカーを接続
  3. 電圧・電流チェッカーを経過時間表示モードに変更
  4. 電圧・電流チェッカーとZ2を接続
  5. X Performance でタイムラプス撮影(今回は30秒間隔)
  6. 充電完了後、タイムラプス動画から頑張ってデータを書き出す
  7. グラフ化

RT-USBVAC3QC にデータのロギング機能がないため、定期的に表示を記録する必要があり、 定期的にメモるのも大変なのでタイムラプス撮影を用いた。その際、"TimeLapse Video" というアプリの無料版を使用した。

RT-USBVAC3QC には積算電流(mAh)を表示する機能があるが、電圧が変化する可能性を考えると電力量(Wh)の方が知りたいので特に使用せず、電力量は自分で計算することにした。 また、初めて使うタイムラプス撮影の撮影間隔が正しいのかどうかわからなかったので、 RT-USBVAC3QC は経過時間表示とした。

今回は約30秒ごとの計測である。そのため、計測時の微妙な値のブレが30秒分に増幅されているはずであるが、積分すると値のブレは無視できると思われるので気にしないことにする。また、値の急激な変化に対する追従が平均15秒遅れることになるが、なめらかな変化の部分は正確だと考えられるので、これも今回は無視した。

なお、充電は扇風機の風をあてながら行った。

接続の様子(実験後)
f:id:KiKibits:20160816235022p:plain

実験結果

f:id:KiKibits:20160816195603p:plain f:id:KiKibits:20160816195612p:plain

電圧はグラフでは一定に見えるが、全体を通して微増を続けた。開始時は約8.58Vで終了直前は約8.87Vであった。

電流の変化は、1.25A前後でほぼ一定の区間、0.9A前後でほぼ一定の区間、徐々に減っていく区間、の3段階がある。

電圧がほぼ一定なので電力のグラフは電流のグラフとほぼ同じになっている。

電力量は途中までは直線的に増えていき、傾きが減少し、その後滑らかに増え方が減るという綺麗なグラフになった。

考察

電圧が 5V ではなく、9V 近い値になっているので、QC2.0 で充電出来たと考えられる。 PowerCore+ の PowerIQ、VoltageBoost の関与についてはよくわからない。

バッテリーのスペックである 12.2Wh を超えているが、"効率" が 100% でもないはずなので特に問題ないと思われる。最終的な電力量が 14.1Wh となっているので、バッテリーが新品でスペック通りだとすると、"効率" は 86~87% だと考えられる。

電池には詳しくないが、ここでいう "効率" が "充放電効率" と同じものだとすると、リチウムイオン電池の充放電効率が 80~90% らしいので、新しいバッテリーはスペック通りで新品同様ではないかと考えられる。

感想

RT-USBVAC3QC にロギング機能がないので、タイムラプス動画からのデータ書き出しが超面倒だった。特に、後半映り込みで表示がほぼ見えないという状況になって嫌になった。

QC2.0 対応で、ロギング機能と電力量計算機能がついている測定器があればいいんだけど・・・