parent
f6bcaae4b9
commit
ce8fe41bd4
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user