Submission #3: jincongho (#482)

This commit is contained in:
Jin Cong Ho 2024-01-19 20:40:05 +00:00 committed by GitHub
parent f6bcaae4b9
commit ce8fe41bd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -31,7 +31,6 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* Changelog (based on Macbook Pro Intel i7 6-cores 2.6GHz): * Changelog (based on Macbook Pro Intel i7 6-cores 2.6GHz):
@ -123,13 +122,31 @@ public class CalculateAverage_jincongho {
// } // }
// scalar implementation // scalar implementation
// public static int hashCode(final MemorySegment array, final long offset, final short length) {
// final long limit = offset + length;
// int h = 1;
// for (long i = offset; i < limit; i++) {
// h = 31 * h + UNSAFE.getByte(array.address() + i);
// }
// return h;
// }
// fxhash
public static int hashCode(final MemorySegment array, final long offset, final short length) { public static int hashCode(final MemorySegment array, final long offset, final short length) {
final long limit = offset + length; final int seed = 0x9E3779B9;
int h = 1; final int rotate = 5;
for (long i = offset; i < limit; i++) {
h = 31 * h + UNSAFE.getByte(array.address() + i); int x, y;
if (length >= Integer.BYTES) {
x = UNSAFE.getInt(array.address() + offset);
y = UNSAFE.getInt(array.address() + offset + length - Integer.BYTES);
} }
return h; else {
x = UNSAFE.getByte(array.address() + offset);
y = UNSAFE.getByte(array.address() + offset + length - Byte.BYTES);
}
return (Integer.rotateLeft(x * seed, rotate) ^ y) * seed;
} }
/** Vectorized Key Comparison **/ /** Vectorized Key Comparison **/
@ -209,7 +226,7 @@ public class CalculateAverage_jincongho {
} }
else { else {
index = (index + 1) & KEY_MASK; index = (index + 1) & KEY_MASK;
keyOffset += KEY_SIZE; keyOffset = KEYS.address() + (index * KEY_SIZE);
} }
} }
@ -254,7 +271,7 @@ public class CalculateAverage_jincongho {
* Measurement Aggregation (for all partitions) * Measurement Aggregation (for all partitions)
* Simple Concurrent Hash Table so all partitions can merge concurrently * Simple Concurrent Hash Table so all partitions can merge concurrently
*/ */
protected static class ResultAggr extends ConcurrentHashMap<ResultAggr.ByteKey, ResultAggr.Measurement> { protected static class ResultAggr extends HashMap<ResultAggr.ByteKey, ResultAggr.Measurement> {
public static class ByteKey implements Comparable<ByteKey> { public static class ByteKey implements Comparable<ByteKey> {
private final MemorySegment data; private final MemorySegment data;
@ -270,10 +287,8 @@ public class CalculateAverage_jincongho {
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (length != ((ByteKey) other).length) return (length == ((ByteKey) other).length)
return false; && !VectorUtils.notEquals(data, offset, ((ByteKey) other).data, ((ByteKey) other).offset, length, VectorUtils.BYTE_SPECIES);
return !VectorUtils.notEquals(data, offset, ((ByteKey) other).data, ((ByteKey) other).offset, length, VectorUtils.BYTE_SPECIES);
} }
@Override @Override
@ -311,8 +326,8 @@ public class CalculateAverage_jincongho {
} }
public ResultAggr(int initialCapacity, float loadFactor, int concurrencyLevel) { public ResultAggr(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, concurrencyLevel); super(initialCapacity, loadFactor);
} }
public Map toSorted() { public Map toSorted() {
@ -326,9 +341,9 @@ public class CalculateAverage_jincongho {
private final MemorySegment data; private final MemorySegment data;
private long offset; private long offset;
private final long limit; private final long limit;
private final ResultAggr result; private final PartitionAggr result;
public Partition(MemorySegment data, long offset, long limit, ResultAggr result) { public Partition(MemorySegment data, long offset, long limit, PartitionAggr result) {
this.data = data; this.data = data;
this.offset = offset; this.offset = offset;
this.limit = limit; this.limit = limit;
@ -338,7 +353,7 @@ public class CalculateAverage_jincongho {
@Override @Override
public void run() { public void run() {
// measurement parsing // measurement parsing
PartitionAggr aggr = new PartitionAggr(); final PartitionAggr aggr = this.result;
// main loop (vectorized) // main loop (vectorized)
final long loopLimit = limit - (VectorUtils.BYTE_SPECIES.length() * Math.ceilDiv(100, VectorUtils.BYTE_SPECIES.length()) + Long.BYTES); final long loopLimit = limit - (VectorUtils.BYTE_SPECIES.length() * Math.ceilDiv(100, VectorUtils.BYTE_SPECIES.length()) + Long.BYTES);
@ -402,7 +417,7 @@ public class CalculateAverage_jincongho {
} }
// measurement result collection // measurement result collection
aggr.mergeTo(result); // aggr.mergeTo(result);
} }
} }
@ -435,15 +450,25 @@ public class CalculateAverage_jincongho {
// partition aggregation // partition aggregation
var threadList = new Thread[processors]; var threadList = new Thread[processors];
ResultAggr result = new ResultAggr(1 << 14, 1, processors); PartitionAggr[] partAggrs = new PartitionAggr[processors];
for (int i = 0; i < processors; i++) { for (int i = 0; i < processors; i++) {
threadList[i] = new Thread(new Partition(data, partition[i], partition[i + 1], result)); if (partition[i] == data.byteSize())
break;
partAggrs[i] = new PartitionAggr();
threadList[i] = new Thread(new Partition(data, partition[i], partition[i + 1], partAggrs[i]));
threadList[i].start(); threadList[i].start();
} }
for (var thread : threadList) {
thread.join();
}
// result
ResultAggr result = new ResultAggr(1 << 14, 1);
for (int i = 0; i < processors; i++) {
if (partition[i] == data.byteSize())
break;
threadList[i].join();
partAggrs[i].mergeTo(result);
}
System.out.println(result.toSorted()); System.out.println(result.toSorted());
} }