私は複数の次元で座標をハッシュするメソッドにスレッドサポートを追加しようとしています。ここでの長期目標は、FNV1A
ハッシュを含めることですが、Hash
メソッドの座標配列を初期化するとすぐに減速が表示されます。アレイの初期化がマルチスレッド化を遅らせているのはなぜですか?
私は100万回繰り返します.1回分のスレッドでは、約300msのストップウォッチ時間があります。 8スレッドの場合、〜6000msにバンプする。
これは間違った共有の問題ですか?もしそうなら、私の心配は、パディングとオフセットが配列に注入されるとハッシュが劣化することです。ローカル配列を使ってこれを実行するための助けがあれば、大歓迎です。どうもありがとう!
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
}
私はまだ統一のスレッドを使用していなかったので、私はこれについてはよく分からないが、私はMonoBehaviour派生クラスが(それから継承されている以上の機能で)マルチスレッドに問題があると思います。 –
新しい配列を割り当てるためのオーバーヘッドでなければなりません。 2つのオプションがあります:配列の代わりに固定量のintを使ってFNV1Aを使用するか、スレッドごとに1つずつ配列を事前に割り当てる。 –
@TamasHegedus百万回の反復と1つのスレッドで、約300msのストップウォッチ時間を得ていたことに気付くと役に立ちます。 8にぶつけて〜6000msに時間を押しました。それは配列オーバーヘッドのようには見えません。その情報を投稿にも追加します。 –