ネットワーク その5 圧縮

限られたネットワーク帯域の中では、送信するデータを圧縮することは非常に重要なことです。

Zip等の一般的な圧縮アルゴリズムはネットワークゲーム向けではありません。これらの圧縮はある程度のデータ量がある場合は効率良い圧縮が期待できますが、ネットワークパケットのように小さいデータを圧縮するには不向きです。ここで必要なのは20バイトのデータを10バイトにするような圧縮方法です。

初心者がよく考える手法として、送信側で複数のパケットを続けてバイトストリームして一般的な圧縮アルゴリズムを使って圧縮し、圧縮されたデータをパケットに分割して送受信するというものがあります。確かに圧縮率は高くなるのですが、この手法には致命的名欠点があります。この手法では、圧縮したデータを展開するに全てのパケットが失われること無く、順番に配信される必要があります。この為にはSenDataOptions.ReliableInOrderを使う必要があり、レイテンシが増加する原因になってしまいます。

また、変化量(前の状態との差)を送ることで全体のデータを送るより少ないデータ量で済ますことができますが、この手法も一般的な圧縮アルゴリズムを使うのと一緒で、全てのデータが順番に送信されるという保障があるときにのみ使える手法です。

 

通常は古典的なビットフィールドをまとめたり、量子化を使った方が良い結果になります。これらの手法は4KBのRAMを積んだ8ビットマイコン時代に良く使われたものですが、ギガバイト単位のデータを扱える.Netの世界では忘れ去られた手法でもあります。

例えば、文字列を送るのでなく、整数のIDかenum値を送る。

もし、行列が回転と移動の組み合わせで、スケールや、せん断、射影をしないと判っているのなら行列データを送らない。変わりに12バイトのVector3であるMatrix.Translateと、16バイトのQuaternion.CreateFromRotationMatrix(matrix)を送ります。これで64バイトの行列データが28バイトに圧縮されたことになります。

以下、次回に続く。

原文
http://blogs.msdn.com/shawnhar/archive/2007/12/22/network-compression.aspx