ÇHS'ye daha hızlı bir alternatif nedir?


27

Bir dsPIC’den bir PC’ye veri aktarımı yapıyorum ve hata olmadığından emin olmak için 512 baytlık her bloğa 8-bit CRC yapıyorum. CRC kodum etkinken yaklaşık 33KB / s, onsuz 67KB / s alıyorum.

Daha hızlı olacağını kontrol etmek için bazı alternatif hata algılama algoritmaları nelerdir?


5
ÇHS kendisi nasıl uygulanmaktadır? Bitsel? Sonra tablo tabanlı bir yönteme geçin. Bytewise? Tablo büyüklüğünün artırılmasıyla ilgili alan, karmaşıklık ve zaman değişiminin, örneğin 16 bite (bir kerede iki baytta çalışacak, ancak 64 KB'lik masa depolama alanı alacağı) düşünün.
Aidan Cully

RAM'de sadece 16KB ve ROM'da 128KB var, bu yüzden 64KB'lık bir masa bir seçenek değil.
FigBug

1
Yani 256 baytlık bir tablo mu kullanıyorsunuz? veya bit yönünde CRC? Bitsel yapıyorsanız, bytewise (256 baytlık bir tabloyla) 8 kat daha hızlı olur.
Aidan Cully


1
67kb / s ila 33kb / s? Diğer işlemlerin neler içerdiğinden emin değilim, ama bu bir PIC için bile biraz ek yük gibi görünüyor. Belki performansınızı engelleyen başka sorunlar var?
Rei Miyasaka

Yanıtlar:


41

CRC'den daha hızlı seçenekler olsa da, eğer kullanırsanız, bir dereceye kadar hata algılama özelliğinden ödün vermeniz muhtemeldir. Hata algılama gereksinimlerinizin ne olduğuna bağlı olarak, alternatif olarak uygulamanıza göre optimize edilmiş CRC kodunu kullanabilirsiniz.

CRC'nin diğer seçeneklerle karşılaştırılması için Martin Thompson tarafından verilen mükemmel cevaba bakınız .

Bu konuda yardımcı olacak bir seçenek, düzinelerce crc model ve algoritma kombinasyonları için C kaynak kodu oluşturabilen bir araç (python 1 ile yazılmış ) olan pycrc'dir . Bu, farklı kombinasyonları seçerek ve kıyaslayarak kendi uygulamanız için hızı ve boyutu optimize etmenize olanak sağlar. 1: Python 2.6 veya üstünü gerektirir.

Bu destekler crc-8 modeli , aynı zamanda destekler crc-5, crc-16ve crc-32diğerleri arasında. Algoritmalar gelince bit-by-bit, bit-by-bit-fastve destekler table-driven.

Örneğin (arşivi indirerek):

$ 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

Tek baytlık arama yerine (256 baytlık arama tablosu ile) çift baytlık aramalar (256 baytlık arama tablosu) kullanarak belirtme gibi eğlenceli şeyler bile yapabilirsiniz.

Örneğin (git deposunu klonlamak):

$ 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

Bellek ve hız sınırlamalarınız göz önüne alındığında, bu seçenek hız ve kod boyutu arasında en iyi uzlaşma olabilir. Emin olmanın tek yolu buna rağmen kıyaslama yapmak olacaktır.


Pycrc git depo üzerinde github onun olduğu gibi sorun izleyici , ama aynı zamanda indirilebilir sourceforge .


PIC için bir şeyler yazan insanların çoğunun C kullandığını sanmıyorum, ancak bu olabilir.
Billy ONeal

4
@Billy - Gerçekten mi? Ben C. kullanmıyordum ticari PIC için gelişmekte herkes rastlamak sanmıyorum ben kesinlikle bu günlerde montajcı için sabrım yok ve iyi yapılandırılmış C oldukça kompakt sona erebilir.
Mark Booth,

Bir dsPIC kullanıyorum ve C kullanıyorum
FigBug

@FigBug - Teşekkürler, cevabımı beğendiğinize sevindim. Bazı kıyaslama testleri yapıyorsanız, cevabımı sonuçlarınızla düzenlemek için çekinmeyin. Algoritmaların her birinin uygulama hacminiz ve hafıza alanınız açısından ne kadar fark yarattığını bilmek isterim.
Mark Booth,

1
Burada pyCrc için başka bir oy. farklı kısıtlamalara sahip çeşitli projelerde kullanmak ve bu harika.
Vicky

11

Basit bir bitlik parite (temel olarak verilerin üzerinde tekrar tekrar XOR yapılması), alabileceği kadar hızlıdır. Yine de bir CRC'nin hata kontrolünden çok kaybedersiniz.

Sözde kodda:

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

1
Buna bir süre önce baktım. Ben xor yerine toplamanın biraz daha iyi çalıştığına inanıyorum . (normalde, toplamı her şey ve sonra sağlama olarak toplamının 2'ye tümleyenini iletmek alıcısı günü, toplamı her şey bu alınan sağlama toplamı dahil sonuç eğer onun tüm iyi ve olmayan 0 aksi 0'dır...)
quickly_now

1
@quickly: Bu ikisi arasında önemli bir fark olduğunu sanmıyorum - hiçbir yöntem de, bu işlerin bozulmadığına dair bir güvence sağlamıyor. Eklemek hedef mimaride daha hızlı ise, elbette bunun yerine kullanın.
Billy ONeal,

7
Hatırladım: ADD ve XOR arasındaki en büyük fark, çoklu bit hatalarının daha az tespit edilebilirliği olduğudur. Bir bayt akışı durumunda, aynı bit pozisyonundaki hatalar XOR kullanılarak iptal edilir. ADD kullanırken, bitlerin sağlama toplamı baytı boyunca yayılması, bu durumun daha belirgin olduğunu gösterir. (Bununla birlikte, bayt akışı boyunca yayılan farklı bitlerdeki çoklu bit hatalarının, o zamanki koşullara bağlı olarak daha az saptanması muhtemeldir). Bunun gibi herhangi bir sağlama toplamı düzenlemesi, çoklu bit hataları için KORKUNÇtur, bu nedenle oldukça küçük bir argümandır.
hızla_doğruyu

XOR, CRC'den daha az faydalıdır.

3
@ Thorbjørn: Cevabımda bunu kabul ettiğime inanıyorum. :)
Billy ONeal

10

Çeşitli sağlama toplamı ve CRC'lerin performansını yerleşik bir bağlamda karşılaştıran gerçekten iyi bir makale:

Gömülü Ağlarda Sağlama Toplamı Etkinliği

Sonuçlardan bazı alıntılar (tespit edilemeyen hata olasılığı çalışmalarına dayanarak):

Patlama hataları hakim olduğunda

XOR, ikisinin tamamlayıcı ilavesi ve CRC sağlama toplamları, birinin tamamlayıcı ilavesi Fletcher ve Adler sağlama toplamlarından daha iyi hata algılama performansı sağlar.

Diğer uygulamalarda

hata tespiti amacıyla mümkün olduğunda bir “iyi” CRC polinomu kullanılmalıdır.

Hesaplama maliyeti çok kısıtlıysa

(sizin durumunuzda olduğu gibi) kullanın (etkinlik sırasına göre):

Diğer teklifler:

Fletcher checksum, Adler checksum'dan daha düşük hesaplama maliyetine sahiptir ve popüler inanışın aksine, çoğu durumda da daha etkilidir.

ve

Yeni tasarımlarda bir XOR sağlama toplamı kullanma genel uygulamasını sürdürmek için genellikle hiçbir neden yoktur, çünkü ek tabanlı bir sağlama toplamı ile aynı yazılım hesaplama maliyetine sahiptir, ancak hataları tespit etmede sadece yarısı kadar etkilidir.


1
Bir bonus olarak, bir Fletcher checksum'un uygulanması çok kolaydır.
RubberDuck

6

Adler sağlama iletim çarpıtma kontrol için yeterli olmalıdır. Zlib sıkıştırma kütüphanesi tarafından kullanılır ve hızlı ama etkili bir veri bütünlüğü kontrolü sağlamak için Java 3D Mobil Grafik Standardı tarafından kabul edilmiştir.

Gönderen wikipedia sayfası :

Bir Adler-32 sağlama toplamı, iki 16-bit sağlama toplamı A ve B'nin hesaplanması ve bitlerinin bir 32-bit tamsayıda birleştirilmesiyle elde edilir. A, dizgideki bütün baytların toplamı artı B'dir ve B, her adımdaki A'nın bireysel değerlerinin toplamıdır.

Bir Adler-32 çalışmasının başlangıcında, A, 1 ila B ila 0 olarak başlatılır. Toplamlar, modulo 65521 (2 ^ 16 veya 65536'dan küçük en büyük asal sayı) yapılır. Baytlar ağ sırasına (büyük endian) depolanır, B en önemli iki baytı işgal eder.

İşlev şu şekilde ifade edilebilir:

 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, sağlama toplamının hesaplanacağı bayt dizesidir ve n, D'nin uzunluğudur.


Adler32'nin kısa veri akışları için neredeyse işe yaramaz olduğunu unutmayın. Yaklaşık 180 bayta kadar, çok sayıda çarpışma üretir.
greyfade

+1 - CRC ve basit bit paritesi arasında makul bir orta yol.
Billy ONeal,

@greyfade - FigBug, 512 bayt blok kullandığından bahsetti, bu yüzden OP için bir problem olmamalı. Gerçi başka gereksinimleri olan insanlar için not almak güzel.
Mark Booth,

5

Bir CRC kadar hata tespitinde etkili ve daha hızlı olan hiçbir şeyin farkında değilim - daha hızlı olsaydı, insanlar onu kullanırdı.

Basit bir sağlama toplamı deneyebilirsiniz, ancak hataları saptaması çok daha az olasıdır.


2
Hız için bir etkinlik bırakmaya istekliyim.
FigBug

3

Sağlama toplamı mantığının kendisi iyidir ve insanlar daha hızlı algoritmalara yardımcı olabilir.

Bileşeninizin hızını artırmak istiyorsanız, transfer bileşenini doğrulama bileşeninden ayırmak için genel tekniğinizi değiştirmeye bakmanız gerekebilir.

Bunları iki bağımsız öğe olarak (farklı iş parçacıklarında) kullanıyorsanız, tam aktarım hızınızı alabilir ve yalnızca başarısız paketleri yeniden gönderebilirsiniz.

Algoritma şuna benzer:

  • Sunucu bilinen paket boyutlarına ayrılıyor (1K parçaları). Onları "gönderilmek üzere" kuyruğuna sokar.
  • Her paket 16 veya 32 bitlik bir ID VE sağlama toplamı ile gönderilir.
  • Müşteri her paketi alır ve işlenmesi için bir kuyruğa koyar.
  • Ayrı bir iş parçacığında, istemci bir seferde bir paket alır, doğrulama yapar.
    • Başarı durumunda, paketlerin nihai koleksiyonuna eklenir (kimlik sırasına göre)
    • Bir başarısızlıkta başarısız kimliğini tekrar sunucuya rapor eder, bu da tekrar gönderilmek üzere bu paketi sıraya alır.
  • Paketleri aldığınızda ve doğruladığınızda ve kimlikleri doğru sırada (1'den başlayarak) aldıktan sonra, bunları diske yazmaya başlayabilirsiniz (veya ne gerekiyorsa yapın).

Bu, mümkün olan en yüksek hızda aktarmanıza izin verir ve paket boyutunuzla oynarsanız, optimium başarısızlık oranı VS onaylama / tekrar gönderme oranını hesaplayabilirsiniz.


2

Sağlama toplamı geleneksel

(# '+ akışını azalt)

XOR yukarıda verilen şekilde işe yarayabilir

(# 'XOR akışını azalt)

Biraz daha ayrıntılı (daha yavaş) bir şema, seri bağlantılar için standart eşlik kontrolüdür.

Bu seviyede, hız için işlem doğruluğu vardır. Bunlar bazen başarısız olur.

Bir sonraki en karmaşık seviyede, bazı crc / hash tipi şeyler kullanabilirsiniz.

Bir başka tasarım, akış için kullanılan bloğun boyutunu arttırmak olacaktır.

Algoritma seçiminizi ve blok büyüklüğü için parametreleri ayarlamak için gerçek bir hata oranı tahminine sahip olmalısınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.