私はdsPICからPCへのデータ送信を行っており、エラーがないことを確認するために512バイトのブロックごとに8ビットCRCを行っています。CRCコードを有効にすると、約33KB /秒になりますが、それなしでは67KB /秒になります。
チェックアウトする高速な代替エラー検出アルゴリズムは何ですか?
私はdsPICからPCへのデータ送信を行っており、エラーがないことを確認するために512バイトのブロックごとに8ビットCRCを行っています。CRCコードを有効にすると、約33KB /秒になりますが、それなしでは67KB /秒になります。
チェックアウトする高速な代替エラー検出アルゴリズムは何ですか?
回答:
CRCよりも高速なオプションがありますが、それらを使用すると、ある程度のエラー検出機能が犠牲になる可能性があります。エラー検出要件に応じて、代わりにアプリケーションに最適化されたCRCコードを使用することもできます。
CRCと他のオプションとの比較については、Martin Thompsonによる優れた回答を 参照してください。
これを支援するオプションの1つは、pycrcです。これは、crcモデルとアルゴリズムの多数の組み合わせに対してCソースコードを生成できるツール(python 1で記述)です。これにより、さまざまな組み合わせを選択してベンチマークすることにより、アプリケーションの速度とサイズを最適化できます。1:Python 2.6以降が必要です。
それはサポートしていcrc-8
たモデルを、だけでなく、サポートcrc-5
、crc-16
およびcrc-32
他の中。用としてのアルゴリズム、それがサポートしbit-by-bit
、bit-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
メモリと速度の制約を考えると、このオプションは速度とコードサイズの最適な妥協案となるでしょう。確認する唯一の方法は、ベンチマークすることです。
pycrcの gitリポジトリは、上にあるgithubのそのあるとして、問題追跡、それはまた、からダウンロードすることができsourceforgeの。
単純な1ビットパリティ(基本的に、データ自体を何度もXOR演算する)は、取得できる速度とほぼ同じです。ただし、CRCのエラーチェックの多くは失われます。
擬似コードで:
char checksum = 0;
for each (char c in buffer)
{
checksum ^= c;
SendToPC(c);
}
SendToPc(checksum);
組み込みコンテキストでのさまざまなチェックサムとCRCのパフォーマンスを比較する非常に優れた論文:
結論からのいくつかの引用(検出されないエラー確率の研究に基づく):
XOR、2の補数加算、およびCRCチェックサムは、1の補数加算、フレッチャー、およびアドラーチェックサムよりも優れたエラー検出パフォーマンスを提供します。
エラー検出には、可能な限り「適切な」CRC多項式を使用する必要があります
(あなたの場合のように)、使用する(効果の順に):
その他の引用:
フレッチャーチェックサムは、Adlerチェックサムよりも計算コストが低く、一般的な考えに反して、ほとんどの状況でより効果的です。
そして
一般に、新しいデザインでXORチェックサムを使用する一般的な方法を継続する理由はありません。XORチェックサムは、追加ベースのチェックサムと同じソフトウェア計算コストを持っていますが、エラーの検出で約半分の効果しかないためです。
アドラーチェックサムは、伝送歪みをチェックするための十分なはずです。Zlib圧縮ライブラリで使用され、Java 3Dモバイルグラフィックス標準で採用され、高速でありながら効果的なデータ整合性チェックを提供します。
ウィキペディアのページから:
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の長さです。
さて、チェックサムロジック自体は優れており、人々はより高速なアルゴリズムを支援できます。
コンポーネントの速度を改善したい場合は、検証コンポーネントから転送コンポーネントを分離するために全体的なテクニックを変更する必要があるかもしれません。
これらを2つの独立したアイテムとして(異なるスレッドで)持っている場合は、転送速度を最大にして、失敗したパケットのみを再送信できます。
アルゴリズムは次のようになります。
これにより、可能な限り最高の速度で送信できるようになり、パケットサイズを試してみると、最適な失敗率と検証/再送率を計算できます。