I'm trying to add threading support to a method that hashes coordinates in multiple dimensions. The long term goal here is to include the FNV1A
hash, but the slowdown appears as soon as simply initializing the coordinate array in the Hash
method.
I iterate a million times, and for 1 thread I get stopwatch times of ~300ms. For 8 threads that time bumps to ~6000ms.
Is this a false sharing issue? If so, my concern is that the hash will deteriorate with padding and offsets injected into the array. Any help on getting this to perform using local arrays would be greatly appreciated. Thanks much!
public class Foo : MonoBehaviour {
#region Fields
private readonly int iterations = 1000000;
private readonly int threadNum = 1;
private int iterationsCompleted = 0;
#endregion
void Start () {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Multithread();
stopWatch.Stop();
UnityEngine.Debug.Log(stopWatch.Elapsed.TotalMilliseconds);
}
private void Multithread() {
for (int i = 0; i < threadNum; i++) {
Hash hash = new Hash();
new Thread(() => {
while (Interlocked.Increment(ref iterationsCompleted) < iterations) {
hash.Get(0, 0, 0);
}
UnityEngine.Debug.Log("Finished thread");
}).Start();
}
while (iterationsCompleted < iterations);
}
}
public class Hash {
#region Fields
// FNV parameters can be found at http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param
private const uint _FNVPrime = 16777619;
private const uint _FNVOffset = 2166136261;
private const uint _FNVMask8 = (1<<8)-1;
#endregion
#region Class Methods
private static uint FNV1A(uint[] data) {
uint hash = _FNVOffset;
int dataSize = data.Length * sizeof(UInt32);
byte[] byteArray = new byte[dataSize];
Buffer.BlockCopy(data, 0, byteArray, 0, dataSize);
for (int i = 0; i < dataSize; i++) {
hash = hash ^ byteArray[i];
hash = hash * _FNVPrime;
}
return hash;
}
public uint Get(int x, int y, uint seed) {
uint[] data = new uint[3] { (uint)x, (uint)y, seed };
//return FNV1A(data);
return 0;
}
#endregion
}