6 typedef signed int Int
;
7 typedef unsigned int UInt
;
8 typedef unsigned long long int Addr64
;
9 typedef unsigned char UChar
;
10 typedef unsigned long int UWord
;
12 static inline UInt
ROL32 ( UInt x
, UInt n
) {
15 x
= (x
<< n
) | (x
>> (32-n
));
19 //////////////////////////////////////////////////////////
30 GuestBytes
* read_one ( FILE* f
)
36 if (feof(f
)) return NULL
;
39 GuestBytes
* gb
= malloc(sizeof(GuestBytes
));
42 r
= fscanf(f
, "GuestBytes %llx %d ", &gb
->ga
, &gb
->nbytes
);
43 if (0) printf("r = %d\n", r
);
47 assert(gb
->nbytes
> 0);
48 assert(gb
->nbytes
< 5000); // let's say
50 Int nToAlloc
= gb
->nbytes
+ (gb
->ga
& 3);
52 gb
->bytes
= malloc( gb
->nbytes
+ nToAlloc
);
53 gb
->actual
= gb
->bytes
+ (gb
->ga
& 3);
57 for (i
= 0; i
< gb
->nbytes
; i
++) {
59 r
= fscanf(f
, "%02x ", &b
);
62 csum
= (csum
<< 1) ^ b
;
65 r
= fscanf(f
, " %08x\n", &esum
);
73 //////////////////////////////////////////////////////////
75 void apply_to_all ( FILE* f
,
76 void(*fn
)( GuestBytes
*, void* ),
80 GuestBytes
* gb
= read_one(f
);
81 if (0) printf("got %llu %d\n", gb
->ga
, gb
->nbytes
);
88 //////////////////////////////////////////////////////////
90 UInt
hash_const_zero ( GuestBytes
* gb
) {
94 UInt
hash_sum ( GuestBytes
* gb
) {
96 for (i
= 0; i
< gb
->nbytes
; i
++)
97 sum
+= (UInt
)gb
->actual
[i
];
101 UInt
hash_rol ( GuestBytes
* gb
) {
103 for (i
= 0; i
< gb
->nbytes
; i
++) {
104 sum
^= (UInt
)gb
->actual
[i
];
110 static UInt
cand0 ( GuestBytes
* gb
)
112 UWord addr
= (UWord
)gb
->actual
;
113 UWord len
= gb
->nbytes
;
115 /* pull up to 4-alignment */
116 while ((addr
& 3) != 0 && len
>= 1) {
117 UChar
* p
= (UChar
*)addr
;
118 sum
= (sum
<< 8) | (UInt
)p
[0];
122 /* vectorised + unrolled */
124 UInt
* p
= (UInt
*)addr
;
125 sum
= ROL32(sum
^ p
[0], 13);
126 sum
= ROL32(sum
^ p
[1], 13);
127 sum
= ROL32(sum
^ p
[2], 13);
128 sum
= ROL32(sum
^ p
[3], 13);
132 /* vectorised fixup */
134 UInt
* p
= (UInt
*)addr
;
135 sum
= ROL32(sum
^ p
[0], 13);
141 UChar
* p
= (UChar
*)addr
;
142 sum
= ROL32(sum
^ (UInt
)p
[0], 19);
149 static UInt
cand1 ( GuestBytes
* gb
)
151 UWord addr
= (UWord
)gb
->actual
;
152 UWord len
= gb
->nbytes
;
153 UInt sum1
= 0, sum2
= 0;
154 /* pull up to 4-alignment */
155 while ((addr
& 3) != 0 && len
>= 1) {
156 UChar
* p
= (UChar
*)addr
;
157 sum1
= (sum1
<< 8) | (UInt
)p
[0];
161 /* vectorised + unrolled */
163 UInt
* p
= (UInt
*)addr
;
165 w
= p
[0]; sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
166 w
= p
[1]; sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
167 w
= p
[2]; sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
168 w
= p
[3]; sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
173 /* vectorised fixup */
175 UInt
* p
= (UInt
*)addr
;
177 sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
184 UChar
* p
= (UChar
*)addr
;
186 sum1
= ROL32(sum1
^ w
, 31); sum2
+= w
;
193 static UInt
adler32 ( GuestBytes
* gb
)
195 UWord addr
= (UWord
)gb
->actual
;
196 UWord len
= gb
->nbytes
;
199 UChar
* buf
= (UChar
*)addr
;
218 return (s2
<< 16) + s1
;
224 //////////////////////////////////////////////////////////
226 UInt (*theFn
)(GuestBytes
*) =
234 Int
cmp_UInt_ps ( UInt
* p1
, UInt
* p2
) {
235 if (*p1
< *p2
) return -1;
236 if (*p1
> *p2
) return 1;
240 Int
nSetBits ( UInt w
)
244 for (i
= 0; i
< 32; i
++)
251 Int toc_nblocks_with_zero
= 0;
252 double toc_sum_of_avgs
= 0.0;
254 void invertBit ( UChar
* b
, UInt ix
, UInt bix
) {
258 void try_onebit_changes( GuestBytes
* gb
, void* opaque
)
261 /* collect up the hash values for all one bit changes of the key,
262 and also that for the unmodified key. Then compute the number
263 of changed bits for all of them. */
265 UInt nHashes
= 8 * gb
->nbytes
;
266 UInt
* hashes
= malloc( nHashes
* sizeof(UInt
) );
269 UInt hInit
, hFinal
, hRunning
;
270 Int dist
, totDist
= 0, nNoDist
= 0;
273 for (byteIx
= 0; byteIx
< gb
->nbytes
; byteIx
++) {
274 for (bitIx
= 0; bitIx
< 8; bitIx
++) {
276 invertBit(gb
->actual
, byteIx
, bitIx
);
277 //invertBit(gb->actual, byteIx, bitIx ^ 4);
279 hRunning
= theFn( gb
);
281 dist
= nSetBits(hRunning
^ hInit
);
283 if (dist
== 0) nNoDist
++;
285 hashes
[hashIx
++] = hRunning
;
287 invertBit(gb
->actual
, byteIx
, bitIx
);
288 //invertBit(gb->actual, byteIx, bitIx ^ 4);
290 if (0) printf(" %02d.%d %08x %d\n",
291 byteIx
, bitIx
, hRunning
^ hInit
, dist
);
294 hFinal
= theFn( gb
);
295 assert(hFinal
== hInit
);
296 assert(hashIx
== nHashes
);
299 printf("%4d measurements, %5.2f avg dist, %2d zeroes\n",
300 (Int
)nHashes
, (double)totDist
/ (double)nHashes
, nNoDist
);
302 printf("%4d measurements, %5.2f avg dist\n",
303 (Int
)nHashes
, (double)totDist
/ (double)nHashes
);
306 toc_nblocks_with_zero
++;
308 toc_sum_of_avgs
+= (double)totDist
/ (double)nHashes
;
313 //////////////////////////////////////////////////////////
318 apply_to_all(f
, try_onebit_changes
, NULL
);
319 printf("\n%d blocks, %d with a zero, %5.2f avg avg\n\n",
320 toc_nblocks
, toc_nblocks_with_zero
, toc_sum_of_avgs
/ (double)toc_nblocks
);
324 //////////////////////////////////////////////////////////