#TUNING by cg
authorClaus Gittinger <cg@exept.de>
Sun, 17 Mar 2019 18:18:27 +0100
changeset 4875 0ad684e3ac77
parent 4874 9ead0ae602b2
child 4876 0ad921aed93f
#TUNING by cg class: CRC32Stream class comment/format in: #examples class: CRC32Stream::CRC32Stream_Castagnoli changed: #nextPutBytes:from:startingAt:
CRC32Stream.st
--- 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'!