Last active
April 22, 2024 12:48
-
-
Save theRealAph/cbc85299d6cd24101d46a06c12a97ce6 to your computer and use it in GitHub Desktop.
Arrays hash code vectorized example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HashCodeExample { | |
static void vload(int[] v0, int[] data, int offset) { | |
for (int i = 0; i < v0.length; i++) { | |
v0[i] = data[i + offset]; | |
} | |
} | |
static void vadd(int[] vd, int[] v0, int[] v1) { | |
for (int i = 0; i < v0.length; i++) { | |
vd[i] = v0[i] + v1[i]; | |
} | |
} | |
static int vadd(int[] vd) { | |
int result = 0; | |
for (int n: vd) { | |
result += n; | |
} | |
return result; | |
} | |
static void vmult(int[] vd, int[] v0, int[] v1) { | |
for (int i = 0; i < v0.length; i++) { | |
vd[i] = v0[i] * v1[i]; | |
} | |
} | |
static final int WIDTH = 4; | |
public static int hashCode(int result, int[] a, int fromIndex, int length) { | |
int end = fromIndex + length; | |
for (int i = fromIndex; i < end; i++) { | |
result = 31 * result + a[i]; | |
} | |
return result; | |
} | |
static int p31(int n) { | |
return switch (n) { | |
case 0 -> 1; | |
case 1 -> 31; | |
default -> 31 * p31(n-1); | |
}; | |
} | |
static final int[] n31powerWIDTH = new int[WIDTH]; | |
static final int[] n31powersToWIDTH = new int[WIDTH]; | |
static { | |
int n = 0; | |
for (int i = WIDTH - 1; i >= 0; --i) { | |
n31powerWIDTH[i] = p31(WIDTH); | |
n31powersToWIDTH[i] = p31(n++); | |
} | |
} | |
public static int vectorizedHashCode(int result, int[] a, int fromIndex, int length) { | |
if (length < WIDTH) { | |
return hashCode(result, a, fromIndex, length); | |
} | |
int offset = fromIndex; | |
int[] sum = new int[WIDTH]; | |
sum[WIDTH - 1] = result; | |
int[] temp = new int[WIDTH]; | |
int remaining = length; | |
while (remaining >= WIDTH * 2) { | |
vmult(sum, sum, n31powerWIDTH); | |
vload(temp, a, offset); | |
vadd(sum, sum, temp); | |
offset += WIDTH; | |
remaining -= WIDTH; | |
} | |
vmult(sum, sum, n31powerWIDTH); | |
vload(temp, a, offset); | |
vadd(sum, sum, temp); | |
vmult(sum, sum, n31powersToWIDTH); | |
offset += WIDTH; | |
remaining -= WIDTH; | |
result = vadd(sum); | |
return hashCode(result, a, fromIndex + offset, remaining); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment