#TUNING by cg
class: CRC32Stream class
comment/format in: #examples
class: CRC32Stream::CRC32Stream_Castagnoli
changed: #nextPutBytes:from:startingAt:
--- a/CRC32Stream.st Sun Mar 17 17:44:03 2019 +0100
+++ b/CRC32Stream.st Sun Mar 17 18:18:27 2019 +0100
@@ -176,7 +176,7 @@
|hashStream n t|
hashStream := CRC32Stream newCastagnoli.
- n := 2000000.
+ n := 4000000.
t := Time millisecondsToRun:[
n timesRepeat:[
hashStream nextPutAll:'12345678901234567890123456789012345678901234567890'.
@@ -541,14 +541,16 @@
#if defined(__x86__) || defined(__x86_64__)
# if defined(__clang__) || defined(__GNUC__)
+ int len, offs;
+
+ // fetch here, but catch non-SmallInt error later
+ len = __intVal(count);
+ offs = __intVal(start) - 1;
+
if (__bothSmallInteger(count, start)) {
- int len, offs;
int objSize;
unsigned char *extPtr;
- len = __intVal(count);
- offs = __intVal(start) - 1;
-
if (__isExternalBytesLike(anObject)) {
OBJ sz = __externalBytesSize(anObject);
@@ -587,31 +589,51 @@
unsigned int *_crcTable = __integerArrayVal( __INST(crcTable) );
unsigned char *cp = extPtr+offs;
unsigned int n = len;
-
- if (__isSmallInteger(__INST(crc))) {
- _crc = (unsigned int) (__intVal( __INST(crc) ));
- } else {
- _crc = __unsignedLongIntVal( __INST(crc) );
+ OBJ crcInst = __INST(crc);
+
+ // fetch here, but catch non-SmallInt error later
+ _crc = (unsigned int) (__intVal( crcInst ));
+ if (! __isSmallInteger(crcInst)) {
+ _crc = __unsignedLongIntVal(crcInst);
}
# if __POINTER_SIZE__ == 8
if (((unsigned INT)cp & 7) == 0) {
// longword aligned
for ( ; n >= 32 ; n -= 32, cp += 32) {
- unsigned INT w0 = ((unsigned INT *)cp)[0];
- unsigned INT w1, w2, w3;
+ unsigned INT w0, w1, w2, w3;
- _crc = _mm_crc32_u64(_crc, w0);
+ w0 = ((unsigned INT *)cp)[0];
w1 = ((unsigned INT *)cp)[1];
+ w2 = ((unsigned INT *)cp)[2];
+ w3 = ((unsigned INT *)cp)[3];
+ _crc = _mm_crc32_u64(_crc, w0);
_crc = _mm_crc32_u64(_crc, w1);
- w2 = ((unsigned INT *)cp)[2];
_crc = _mm_crc32_u64(_crc, w2);
- w3 = ((unsigned INT *)cp)[3];
_crc = _mm_crc32_u64(_crc, w3);
}
- for ( ; n >= 8 ; n -= 8, cp += 8) {
+ if (n >= 16) {
+ _crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[0]);
+ _crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[1]);
+ n -= 16, cp += 16;
+ }
+ if (n >= 8) {
_crc = _mm_crc32_u64(_crc, ((unsigned INT *)cp)[0]);
+ n -= 8, cp += 8;
}
+ if (n >= 4) {
+ _crc = _mm_crc32_u32(_crc, ((unsigned int *)cp)[0]);
+ n -= 4, cp += 4;
+ }
+ if (n >= 2) {
+ _crc = _mm_crc32_u16(_crc, ((unsigned short *)cp)[0]);
+ n -= 2, cp += 2;
+ }
+ if (n >= 1) {
+ _crc = _mm_crc32_u8(_crc, (cp)[0]);
+ }
+ __INST(crc) = __MKSMALLINT(_crc);
+ RETURN (count);
}
# endif // __POINTER_SIZE__ == 8
if (((unsigned INT)cp & 3) == 0) {
@@ -631,7 +653,7 @@
_crc = _mm_crc32_u8(_crc, ch);
}
-
+done:
if ((__POINTER_SIZE__==8) || (_crc <= _MAX_INT)) {
__INST(crc) = __MKSMALLINT(_crc);
} else {
@@ -651,6 +673,7 @@
self primitiveFailed
"Created: / 17-03-2019 / 16:44:27 / Claus Gittinger"
+ "Modified: / 17-03-2019 / 18:09:03 / Claus Gittinger"
! !
!CRC32Stream class methodsFor:'documentation'!