So habe ich ein Design, das CRC32C Prüfsummen enthält Daten, um sicherzustellen, nicht beschädigt wurde. Ich entschied mich dafür, CRC32C zu verwenden, weil ich sowohl eine Softwareversion als auch eine hardwarebeschleunigte Version haben kann, wenn der Computer, auf dem die Software läuft, SSE 4.2Implementierung von SSE 4.2 des CRC32C in Software
Ich gehe durch Intels Entwicklerhandbuch (Vol. 2A), das zu bieten scheint der Algorithmus hinter der crc32
Anweisung. Ich habe jedoch wenig Glück. Intel-Entwicklerhandbuch sagt die folgende:
BIT_REFLECT32: DEST[31-0] = SRC[0-31]
MOD2: Remainder from Polynomial division modulus 2
TEMP1[31-0] <- BIT_REFLECT(SRC[31-0])
TEMP2[31-0] <- BIT_REFLECT(DEST[31-0])
TEMP3[63-0] <- TEMP1[31-0] << 32
TEMP4[63-0] <- TEMP2[31-0] << 32
TEMP5[63-0] <- TEMP3[63-0] XOR TEMP4[63-0]
TEMP6[31-0] <- TEMP5[63-0] MOD2 0x11EDC6F41
DEST[31-0] <- BIT_REFLECT(TEMP6[31-0])
, nun soweit ich sagen kann, ich habe alles getan, bis zur Linie TEMP6
richtig starten, aber ich denke, ich entweder die Polynomdivision Missverständnis sein kann, oder die Umsetzung es falsch. Wenn mein Verständnis korrekt ist, 1/1 mod 2 = 1
, 0/1 mod 2 = 0
, und beide Divides-by-Null sind nicht definiert.
Was ich nicht verstehe ist, wie binäre Division mit 64-Bit und 33-Bit-Operanden arbeiten. Wenn SRC
0x00000000
ist und DEST
0xFFFFFFFF
ist, werden TEMP5[63-32]
alle gesetzten Bits sein, während TEMP5[31-0]
alle nicht gesetzten Bits sein werden.
Wenn ich die Bits von TEMP5
als Zähler zu verwenden, würde es 30 Divisionen durch Null sein, da das Polynom 11EDC6F41
nur 33 Bits lang ist (und es so umzuwandeln, um ein 64-Bit Integer ohne Vorzeichen läßt die oberen 30 Bits nicht gesetzt), und der Nenner ist für 30 Bits nicht gesetzt.
Wenn ich jedoch das Polynom als Zähler zu verwenden, war, die unteren 32 Bits TEMP5
sind ungesetzt, da in dividieren durch Null ergibt, und die oberen 30 Bits des Ergebnisses wäre Null, wenn die oberen 30 Bits der Zähler wäre Null, wie 0/1 mod 2 = 0
.
Bin ich Missverständnis, wie das funktioniert? Einfach nur etwas fehlt? Oder hat Intel wichtige Schritte in der Dokumentation ausgelassen?
Der Grund, warum ich Intels Entwickler-Guide für den scheinbar verwendeten Algorithmus aufgerufen habe, ist, dass sie ein 33-Bit-Polynom verwendeten, und ich wollte Outputs identisch machen, was nicht passierte, wenn ich den 32- Bitpolynom (siehe unten).
uint32_t poly = 0x1EDC6F41, sres, crcTable[256], data = 0x00000000;
for (n = 0; n < 256; n++) {
sres = n;
for (k = 0; k < 8; k++)
sres = (sres & 1) == 1 ? poly^(sres >> 1) : (sres >> 1);
crcTable[n] = sres;
}
sres = 0xFFFFFFFF;
for (n = 0; n < 4; n++) {
sres = crcTable[(sres^data) & 0xFF]^(sres >> 8);
}
Der obige Code erzeugt 4138093821
als Ausgang und die crc32
Opcode erzeugt 2346497208
unter Verwendung der Eingabe 0x00000000
.
Sorry, wenn dies schlecht geschrieben oder unverständlich an Orten, ist es ziemlich spät für mich.
Für diejenigen, die Delphi verwenden, habe ich [Open Source Code geschrieben] (http://blog.synopse.info/post/2014/05/25/New-crc32c%28%29-function-using-optimized -asm-and-SSE-4.2-Befehl) mit der neuen 'crc32'-Hardware-Anweisung, falls verfügbar, und schnellem x86-Asm oder reinem Pascal-Code (unter Verwendung von vorberechneten Tabellen), wenn SSE 4.2 nicht verfügbar ist. Naive-Version rollt mit 330 MB/s, optimierte x86-Asr-Version mit 1,7 GB/s und SSE 4.2-Hardware mit erstaunlicher Geschwindigkeit von 3,7 GB/s (auf Win32- und Win64-Plattformen). –