web-dev-qa-db-ja.com

CRCのより速い代替手段は何ですか?

エラーが発生しないことを確認するために、dsPICからPCへのデータ転送と512バイトのブロックごとに8ビットCRCを実行しています。 CRCコードを有効にすると、約33KB/sが得られますが、それがないと67KB/sになります。

より速くなるチェックアウトするためのいくつかの代替エラー検出アルゴリズムは何ですか?

27
FigBug

CRCよりも高速なオプションがあるかもしれませんが、それらを使用すると、ある程度のエラー検出機能が犠牲になる可能性があります。エラー検出の要件に応じて、代わりにアプリケーションに最適化されたCRCコードを使用することもできます。

CRCと他のオプションの比較については、 Martin Thompson による excellent の回答を参照してください。

これを助ける1つのオプションは、pycrcです(これは、Pythonで記述されたツールです)1Cソースコードcrcモデルアルゴリズムの数十の組み合わせを生成できます。これにより、さまざまな組み合わせを選択してベンチマークすることにより、アプリケーションの速度とサイズを最適化できます。 1:Python 2.6以降が必要です。

crc-8モデルをサポートしていますが、crc-5crc-16crc-32などもサポートしています。 アルゴリズムについては、bit-by-bitbit-by-bit-fastおよびtable-drivenをサポートしています。

例(アーカイブのダウンロード):

$ wget --quiet http://sourceforge.net/projects/pycrc/files/pycrc/pycrc-0.8/pycrc-0.8.tar.gz/download
$ tar -xf pycrc-0.8.tar.gz
$ cd pycrc-0.8
$ ./pycrc.py --model=crc-8 --algorithm=bit-by-bit      --generate c -o crc8-byb.c
$ ./pycrc.py --model=crc-8 --algorithm=bit-by-bit-fast --generate c -o crc8-bybf.c
$ ./pycrc.py --model=crc-8 --algorithm=table-driven    --generate c -o crc8-table.c
$ ./pycrc.py --model=crc-16 --algorithm=table-driven   --generate c -o crc16-table.c
$ wc *.c
   72   256  1790 crc8-byb.c
   54   190  1392 crc8-bybf.c
   66   433  2966 crc8-table.c
  101   515  4094 crc16-table.c
  293  1394 10242 total

256バイトのルックアップテーブルを使用して、シングルバイトのルックアップではなく、デュアルニブルルックアップ(16バイトのルックアップテーブルを使用)を使用して指定するなど、ファンキーなことを行うこともできます。

例(gitリポジトリのクローン):

$ git clone http://github.com/tpircher/pycrc.git
$ cd pycrc
$ git branch
* master
$ git describe
v0.8-3-g7a041cd
$ ./pycrc.py --model=crc-8 --algorithm=table-driven --table-idx-width=4 --generate c -o crc8-table4.c
$ wc crc8-table4.c
  53  211 1562 crc8-table4.c

メモリと速度の制約を考えると、このオプションは速度とコードサイズの間の最良の妥協案になる可能性があります。確かに唯一の方法は、それをベンチマークすることです。


pycrcgitリポジトリは github にあり、その issue tracker にもありますが、 sourceforge からダウンロードできます。

41
Mark Booth

埋め込みコンテキストでのさまざまなチェックサムとCRCのパフォーマンスを比較する非常に優れた論文:

組み込みネットワークのチェックサムの有効性

結論からのいくつかの引用(未検出のエラー確率の調査に基づく):

バーストエラーが支配的な場合

XOR、2の補数加算、およびCRCチェックサムは、1の補数加算、フレッチャー、およびアドラーチェックサムよりも優れたエラー検出パフォーマンスを提供します。

他のアプリケーションでは

エラー検出の目的で、可能な場合は常に「良好な」CRC多項式を使用する必要があります

計算コストが非常に制限されている場合

(あなたの場合のように)、使用してください(効果の順に):

その他の引用:

フレッチャーチェックサムはアドラーチェックサムよりも計算コストが低く、一般的な考えに反して、ほとんどの状況でより効果的です。

そして

新しい設計でXORチェックサムを使用する一般的な方法を続ける理由はありません。これは、追加ベースのチェックサムと同じソフトウェア計算コストを持っていますが、エラーの検出。

11
Martin Thompson

単純な 1ビットパリティ (基本的にそれ自体でデータを何度もXORする)は、可能な限り高速です。ただし、CRCのエラーチェックの多くは失われます。

疑似コード:

char checksum = 0;
for each (char c in buffer)
{
    checksum ^= c;
    SendToPC(c);
}
SendToPc(checksum);
11
Billy ONeal

Adler checksum は、伝送の歪みをチェックするのに十分なはずです。これは、Zlib圧縮ライブラリによって使用され、Java 3Dモバイルグラフィックス標準によって採用され、高速で効果的なデータ整合性チェックを提供します。

wikipedia page から:

Adler-32チェックサムは、2つの16ビットチェックサムAおよびBを計算し、それらのビットを32ビット整数に連結することによって取得されます。 Aは文字列のすべてのバイトの合計に1を加えたものであり、Bは各ステップのAの個々の値の合計です。

Adler-32の実行の開始時に、Aは1、Bは0に初期化されます。合計は65521を法として行われます(2 ^ 16または65536より小さい最大素数)。バイトはネットワーク順(ビッグエンディアン)で格納され、Bは2つの最上位バイトを占有します。

関数は次のように表すことができます

 A = 1 + D1 + D2 + ... + Dn (mod 65521)
 B = (1 + D1) + (1 + D1 + D2) + ... + (1 + D1 + D2 + ... + Dn) (mod 65521)
   = n×D1 + (n-1)×D2 + (n-2)×D3 + ... + Dn + n (mod 65521)

 Adler-32(D) = B × 65536 + A

ここで、Dはチェックサムを計算するバイトの文字列、nはDの長さです。

6
Gnawme

CRCと同じくらい高速でエラー検出に効果的なものは何も知りません-もしあれば、人々は代わりにそれを使用するでしょう。

単純なチェックサムを試すこともできますが、エラーを検出する可能性ははるかに低くなります。

5
Bob Murphy

さて、チェックサムロジック自体は優れており、人々はより高速なアルゴリズムを支援できます。

コンポーネントの速度を向上させたい場合は、全体的な手法を変更して、転送コンポーネントを検証コンポーネントから分離することを検討する必要があるかもしれません。

これらを2つの独立したアイテムとして(異なるスレッド上に)持っている場合、転送速度をフルにして、失敗したパケットのみを再送信できます。

アルゴリズムは次のようになります。

  • サーバーは既知のパケットサイズに分割されます(1Kチャンクなど)。 「送信する」のキューに入れます。
  • 各パケットは、16ビットまたは32ビットのIDとそのチェックサムとともに送信されます。
  • クライアントは各パケットを受信し、処理するためにキューに入れます。
  • 別のスレッドでは、クライアントは一度にパケットを受け取り、検証を行います。
    • 成功すると、パケットの最終コレクション(ID順)に追加されます。
    • 失敗すると、失敗したIDをサーバーに報告し、サーバーはそのパケットをキューに入れて再送信します。
  • パケットを受信して​​検証し、IDが正しいシーケンス(1から始まる)になったら、これらをディスクに書き込む(または必要な処理を行う)ことができます。

これにより、可能な限り最高の速度で送信を行うことができます。パケットサイズを試してみると、最適な失敗率と検証/再送信率を計算できます。

3
Robin Vessey

チェックサムは伝統的です

(# '+ストリームを削減)

上記のXORも機能します

(# 'XORストリームを削減)

少し複雑な(遅い)スキームは、シリアル接続の標準パリティチェックです。

このレベルでは、速度と正確さのトレードオフです。これらは時々失敗します。

次に洗練されたレベルでは、いくつかのcrc/hashタイプのものを使用できます。

別の設計は、ストリームに使用されるブロックのサイズを増やすことです。

アルゴリズムの選択とブロックサイズのパラメーターを調整するには、実際のエラー率の見積もりが必要です。

2
Paul Nathan