【サーバ】ECCメモリ、Registeredメモリ

概要

ECCメモリは、RAM(メモリ)の一種です。
ゲーム用PCでは使いません。計算に時間がかかったり、長時間稼働でもデータの破損が許されなかったりといった要求がある場合に採用されます。具体的には、科学技術計算・金融機関向けのコンピュータで多く採用されていると言われています。

※この記事はサーバ・ワークステーション用のメモリについて書かれたものです。
一般向けのUnbuffered DIMMを解説したものではありません。
ご承知おきください。

種類

表1.メモリモジュールの種類

レジスタバッファ:ありレジスタバッファ:なし
ECC:ありECC Registered DIMMECC Unbuffered DIMM
ECC:なしRegistered DIMMUnbuffered DIMM

表1の左上にある、ECC Registered DIMM (RDIMM)は、中~高価格帯サーバ、ワークステーションで利用されるメモリです。

右上にある、ECC Unbuffered DIMM (ECC UDIMM)は、低価格帯サーバ、ワークステーションでの利用が多いです。近年はあまり見かけません。

右下にある、Unbuffered DIMM (UDIMM)は、デスクトップPCやノートPCで使われます。要は普通のメモリです。

普通のメモリとの比較

メリット

ECCメモリを採用するメリットとして、

・勝手にメモリエラー直してくれるのでコンピュータがクラッシュしづらい
エラー検出が出来る
DRAMたくさん積める(ECC搭載だとRegistered機能が付いていることが多いため)

等があります。かなり大雑把に、「メモリが多く積める上に、ブルースクリーンも減るかもしれないよ」という言い換えができるかもしれません。なお、Googleの研究によると

メモリモジュールでは1つ当たり1年間で平均4000回近い訂正可能なエラーが発生すること、そしてGoogleのサーバでは一般的なPCと違って、エラー訂正符号(Error Correction Code:ECC)を使っているため、そうした問題のほとんどが小さいうちに摘み取られていることを念頭に置く必要がある。したがって、Googleのマシンで発生する訂正可能なエラーは、一般ユーザーのコンピュータでは訂正不可能なエラーになる可能性が高い

DRAM Errors in the Wild: A Large Scale Field Study by Google inc.
http://www.cs.toronto.edu/~bianca/papers/sigmetrics09.pdf

と結論付けられています。メモリ1枚当たり、年間4000回のビット反転が起きていると言えるわけです。

また、この直前には、ECCメモリを積んだ場合でも3台に1台ほど訂正不可能なエラーが発生するとも書かれています。つまり、ECCメモリを使わないで再起動も全くしなかった場合、「1年に何回もブルースクリーンが出るかもしれないよ」と主張しているのです。事実かは分かりません。

※訂正不可能なエラーを発生させたビットの値が計算に使われたとき、アプリやコンピュータはクラッシュします。個人の用途なら別に再起動すれば良いだけです。共用ユーザが多いため、あるいは信頼性が最重要なために、この再起動が許容されない科学技術計算や、金融システムなどではECCメモリを使おう(=使っても元が取れるよね)となるのです。

普通のメモリの良さ

・安い
・速度面で優れている

分岐点として、16GBx4=64GBを超える(上回る)メモリを積む場合、ECCメモリが視野に入ってきます。(※あくまで2021年4月時点での技術の話です。)
ECCの恩恵を受けられる個人の用途としては、RAMDisk化して使ったり、Gaussian・MatLabなどの高度な行列計算を用いる研究ソフトが多いのではないかと思います。

一般に、データ損失に対する保護とコストはトレードオフの関係にあります。
従って、ECCメモリは長時間稼働し続ける、研究用途・金融情報処理・サーバなどで選択される傾向があり、ECCメモリモジュールの製造には追加の回路が必要なため高価であるほか、ECCメモリコントローラが誤りを検出するために余分な時間を要するため、(実装によっては)速度面の性能は2~3%下回ると言われ、ゲームには向きません。

2021年現在では、ECCメモリの価格が十分に下がってきており、(オーバークロックなどをしない場合は)速度も十分に出るものが販売されています。
連続稼働予定のワークステーションを導入する場合はこちらを検討しても良いと思います。

ECC対応メモリを使う場合

CPU、チップセット(マザーボードとほぼ同義)、メモリを全てECC対応にする必要があります。CPUは2021年時点の選択肢としては
・Intel Xeon
・AMD Ryzen(公式にサポートはしていない)
・AMD EPYC
・AMD Threadripper
といった感じです。AMDのCPUはどれを買ってもECCが利用可能です。一方、IntelのCPUは、Xeonのみで動作します。Coreシリーズはダメです。メモリのSPDを見て弾いてるっぽいので、多分本当に動作しません。

ECCメモリと非ECCメモリは混ぜてもマザーボードが対応していれば使えます。紛らわしいようですが、UnbufferedメモリとRegisteredメモリは混在出来ません。動作原理が違うためです。コンピュータが起動しません。

ちなみに、「メモリエラーが原因で計算結果が間違って出力されることがある。だからECCメモリを導入すべきである。」という説が広く信じられています。これは嘘です。メモリエラーが起きたとしても計算が途中で止まるだけです。間違った結果が出力されることはありません。

なお8桁しか表示できない電卓で10桁の計算をすれば、誤差が発生します。この現象のことをオーバーフローと呼び、誤差の大きな要因の一つとなっています。メモリエラーとの関係はありません。

詳しい話

レジスタバッファ

レジスタバッファが備えられていると、メモリのクロックがレジスタバッファに格納されタイミングが同期されます。メモリクロックと信号のタイミングが同期されるため、安定したアクセスができます。

例えば、サーバー向け用途の場合、メモリを多く実装したいというニーズがあります。サーバ向けのアプリケーション(データベース等)の場合、メモリの速度やレイテンシのわずかな差よりも、メモリの搭載量がそのまま性能に直結しがちなためです。そのため「積めるだけ積む」というニーズが多く、これに対応する必要があります。

ここで、既存のDIMMを複数枚装着した場合の信号ラインの負荷が問題になります。図1は、3枚のNon-Parity 1-Bank DIMMを装着したケースの画像です。ひとつのメモリチップが8bit分のデータ幅をサポートするため、8個のチップで64bitになります。

図1.Non Parity 1-Bank DIMM(Unbuffered DIMM)での信号ライン

図のD0~D63はデータパスで、3枚のDIMMを装着すると1本の信号ラインに3個のメモリチップがぶら下がる計算になります。この程度ならさほど問題はありません。これが2バンクになると6個がぶら下がることになるのですが、これもまだ問題にはなりません。
問題なのは、赤で示した“Address/Command”線(信号ライン)の方です。

Address/Command線はひとつのDIMMの中でさらに分岐するので、図1のパターンでは、8×3=24個のメモリチップに信号を渡す必要があります。これがパリティ(ECCメモリで使われるエラー訂正用チップ)付きの場合は27個に増え、さらに2バンク構成だと54個になります。

Address/Command線が駆動すべきメモリチップの数は、データパスに比べて猛烈に多いのです。
結果、1枚や2枚のDIMMなら動くのに、3~4枚やマルチバンクタイプのDIMMを利用するケースで動作がおかしくなる場合が出てくるようになりました。

この問題の解決策が、「DIMM上にレジスタ(バッファ)を置き、ここで信号を整えてやる」というアイデアです。次の図2のように、DIMM上に小さなレジスタを置き、Address/Commandの信号を一旦ここで受けます。それから、レジスタより各メモリチップに信号を分配します。これで、Address/Commandの信号はDIMMあたり1個のレジスタだけを駆動すれば良いので、データパスと同じ条件になるわけです。

図2.Registered DIMMでの信号ライン。DIMM上にある四角がレジスタ

こうして、パリティを積んだタイプを”Registered DIMM”、そうではない普通のものを”Unbuffered DIMM”と呼びます。(図3

図3.マルチバンクでのUnbuffered DIMM(左)およびRegistered DIMM(右)の信号ラインの違い。赤がAddress/Command線で、青はデータパス

最近のPCはゲーム用途でも4枚以上積んでいるものも多く、十分大容量じゃないか、と思われるかもしれません。しかし、こんなRegistered DIMMにも弱点があります。

まず、レジスタを介するため、Address/Commandの信号に1~2%程度の遅延が発生します。これをカバーするためには、レジスタでの遅延分だけメモリコントローラが早めに信号を出すか、データ側のタイミングを若干ずらして調整を取るしかない、ということになるわけです。
大容量のメモリを搭載するサーバならこの欠点は許容されます。しかし、小容量で性能を重視するPC(主にゲーム用途)では、データ側のタイミングをずらした分遅延が発生し、若干の性能低下を招きます。Registered DIMMが使われない主な理由がこれです。

さらに、チップを余分に搭載する分、価格が高くなります。実際にはRegistered DIMMが必要となるのはサーバのみなので、当然製造数量も少なくなり価格も高くなります。このため、家庭/事務用PC向けに採用されにくくなっています。

なお、チップセット(マザーボード)では、「Registered DIMMのみ対応」と「Unbuffered DIMMのみ対応」という両者は信号レベルで等価です。家庭用PCではRegistered DIMMのテストをせず、サーバは逆にUnbuffered DIMMをサポートしない、つまり該当の動作の「検証」をしていないというだけだったりします。
そのため、DIMM上のSPDを見て、サポートしないタイプのメモリは弾く(認識しない)といった処理をしていることが多いようです。

ECC(エラー訂正機能)

エラー訂正機能が備えられていると、メモリ内のデータが誤っていた場合でもエラー訂正が出来ます。エラー訂正によりメモリの信頼度が高まります。

メモリに格納するデータには、厳密さが求められるものと、そうでないものがあります。
例えば画像データなどは、1bit程度違っていても実使用上その間違いは問題ないかもしれませんが、ネットワークのパケットデータなどはそうではありません。
しかし、メモリ内のデータはソフトエラーやSEU(Single Event Upset)の影響で書き換わってしまうことがあります。
この対応として、メモリに発生したエラーを自動的に訂正するECC(Error Checking and Correction)という仕組みが存在します。

図4のように、ECC付きのメモリの場合、大抵はモジュール上にチップが9枚搭載されます。

図4.ECCなしとECCありのメモリの違い

図5は、実際のECCメモリの画像です。
中央に一つ余分なチップが付いているのが分かります。
これを、パリティ用メモリチップと呼んでいます。

さて、パリティとは何でしょうか。ECCメモリの前に、一旦この説明をします。

パリティ

最近のPCのメモリには必ず搭載されています。そのため、パリティという言葉自体、聞かなくなっています。

パリティは、通常のデータにエラー訂正用のパリティを付け加えて、エラーが起きても発見できるようにする技術です。通常のメモリでは8bitにつき1bitのパリティを加えて合計が偶数になるようにします。
表2にパリティの原理を示します。

表2.パリティの原理

  データ パリティ 合計
bit 0 0 1 1 0 0 0 0 0 偶数
  データ パリティ 合計
bit 1 0 1 0 1 0 0 0 1 偶数

表2のように、パリティを合わせた9bitの合計は必ず偶数となっています。もし仮に、この中で1つエラーが発生してそのビットが反転したとすると、合計が奇数となるのでエラーが発生したことが分かります。ただ、どこがエラーかまでは分からないので、もう一度データの読み込みや書き込みをやり直す必要があります。
実は、同時に偶数個のデータが反転した場合、エラーが検出できないという欠点もあります。

ECC

前述のパリティでは、エラーが発見できても箇所が分からないために、「修復が出来ない」「偶数個のエラーが検出できない」という欠点がありました。

そこで、パリティを一組多く設けることにしました。1つのエラーであれば修復でき、2個以上でも検出できるようにしたのがECCメモリです。

先ほどは8bitに1つのパリティを組み合わせました。それを8セット束ねて1セットのパリティを組み合わせます(表2)。

表3.ECCの原理

  データ パリティ 合計
データ 1 0 1 0 1 0 0 0 1 偶数
1 1 1 0 0 0 1 1 1 偶数
1 0 0 0 1 0 0 1 1 偶数
0 0 1 0 0 1 0 0 0 偶数
0 1 1 0 1 1 1 0 1 偶数
0 0 1 1 1 0 0 1 0 偶数
1 0 0 0 0 0 1 1 1 偶数
1 0 0 0 1 0 0 0 0 偶数
パリティ 1 0 1 1 1 0 1 0 1 偶数
合計 偶数 偶数 偶数 偶数 偶数 偶数 偶数 偶数 偶数  

こうして、仮に1つのエラーが発生した場合、そのビットの縦横でエラーが検出されるので場所が特定できます。また、2か所以上のエラーでも、かなりの精度で検出することができます。
この方法は水平パリティ・垂直パリティと呼ばれ、メモリ以外でもよく使われています。

では、行と列が重なるように上手い具合に3箇所にエラーが発生した場合はどうなるのでしょうか。残念ながら、この場合、エラーがあることは分かりますが、箇所は特定できないので、修復はできません。
というか最早この状況だと計算機自体がまともに動作していないものと思われます。


※補足1
図5に示したように、多くの市販のECCメモリは片面に9個のメモリチップが搭載されるようになっています。これは、ECC搭載とECCなしの両方のメモリで基板を共通設計にしているためです。8個のデータ用メモリチップと、1個のパリティ用(ECC用)メモリチップが片面に搭載できるように設計されているのです。すなわち、このような設計パターンの場合、ECCなしのモジュールは中央にECC用メモリチップのための空きパターンがあります。

※補足2
1ビットの誤り訂正と2ビットの誤り検出をハミング符号/シャオ符号と呼びます。
一般に使われることは少ないのですが、2ビットの誤り訂正と3ビットの誤り検出や、1ニプル(=4ビット)の誤り訂正と2ニプルの誤り検出符号を持つものもあります。
実用上は、同じデータを別の方法でそのままコピーして別の領域に書き込んで比較することによって多ビット訂正を行う、インターリープという手法が多く用いられます。

さらに、サーバ向けCPU(プロセッサ)の多くはキャッシュメモリでもこのような誤り訂正符号を使っています。具体的には、Intel Itanium, Xeon, AMD Athlon, Opteron, DEC Alpha 21264等でこの仕組みが使われています。

※補足3
ECCメモリの説明で、「同時に2つのエラーが~」という言葉が使われることがあります。基本的に、ECCメモリのエラー訂正は、データを読み出すときに行われます。
つまり、この「同時に」というのは「そのメモリに最後に書き込まれてから、次に読み込まれた瞬間まで」のことなのでした。
サーバやワークステーションでは、メモリスクラビングといって、全領域に再度書き込み処理をする仕様になっているシステムもあります。

作成者: rarafy

2013年くらいからUnityを触っているかもしれません。 特に書くこともありませんが、趣味は部屋の掃除です。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です