エラーが発生しないことを確認するために、dsPICからPCへのデータ転送と512バイトのブロックごとに8ビットCRCを実行しています。 CRCコードを有効にすると、約33KB/sが得られますが、それがないと67KB/sになります。
より速くなるチェックアウトするためのいくつかの代替エラー検出アルゴリズムは何ですか?
CRCよりも高速なオプションがあるかもしれませんが、それらを使用すると、ある程度のエラー検出機能が犠牲になる可能性があります。エラー検出の要件に応じて、代わりにアプリケーションに最適化されたCRCコードを使用することもできます。
CRCと他のオプションの比較については、 Martin Thompson による excellent の回答を参照してください。
これを助ける1つのオプションは、pycrcです(これは、Pythonで記述されたツールです)1)Cソースコードcrcモデルとアルゴリズムの数十の組み合わせを生成できます。これにより、さまざまな組み合わせを選択してベンチマークすることにより、アプリケーションの速度とサイズを最適化できます。 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
メモリと速度の制約を考えると、このオプションは速度とコードサイズの間の最良の妥協案になる可能性があります。確かに唯一の方法は、それをベンチマークすることです。
pycrcgitリポジトリは github にあり、その issue tracker にもありますが、 sourceforge からダウンロードできます。
埋め込みコンテキストでのさまざまなチェックサムとCRCのパフォーマンスを比較する非常に優れた論文:
結論からのいくつかの引用(未検出のエラー確率の調査に基づく):
XOR、2の補数加算、およびCRCチェックサムは、1の補数加算、フレッチャー、およびアドラーチェックサムよりも優れたエラー検出パフォーマンスを提供します。
エラー検出の目的で、可能な場合は常に「良好な」CRC多項式を使用する必要があります
(あなたの場合のように)、使用してください(効果の順に):
その他の引用:
フレッチャーチェックサムはアドラーチェックサムよりも計算コストが低く、一般的な考えに反して、ほとんどの状況でより効果的です。
そして
新しい設計でXORチェックサムを使用する一般的な方法を続ける理由はありません。これは、追加ベースのチェックサムと同じソフトウェア計算コストを持っていますが、エラーの検出。
単純な 1ビットパリティ (基本的にそれ自体でデータを何度もXORする)は、可能な限り高速です。ただし、CRCのエラーチェックの多くは失われます。
疑似コード:
char checksum = 0;
for each (char c in buffer)
{
checksum ^= c;
SendToPC(c);
}
SendToPc(checksum);
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の長さです。
CRCと同じくらい高速でエラー検出に効果的なものは何も知りません-もしあれば、人々は代わりにそれを使用するでしょう。
単純なチェックサムを試すこともできますが、エラーを検出する可能性ははるかに低くなります。
さて、チェックサムロジック自体は優れており、人々はより高速なアルゴリズムを支援できます。
コンポーネントの速度を向上させたい場合は、全体的な手法を変更して、転送コンポーネントを検証コンポーネントから分離することを検討する必要があるかもしれません。
これらを2つの独立したアイテムとして(異なるスレッド上に)持っている場合、転送速度をフルにして、失敗したパケットのみを再送信できます。
アルゴリズムは次のようになります。
これにより、可能な限り最高の速度で送信を行うことができます。パケットサイズを試してみると、最適な失敗率と検証/再送信率を計算できます。
チェックサムは伝統的です
(# '+ストリームを削減)
上記のXORも機能します
(# 'XORストリームを削減)
少し複雑な(遅い)スキームは、シリアル接続の標準パリティチェックです。
このレベルでは、速度と正確さのトレードオフです。これらは時々失敗します。
次に洗練されたレベルでは、いくつかのcrc/hashタイプのものを使用できます。
別の設計は、ストリームに使用されるブロックのサイズを増やすことです。
アルゴリズムの選択とブロックサイズのパラメーターを調整するには、実際のエラー率の見積もりが必要です。