Search Unity

Feedback NativeHashMap.Clear 4x Performance Improvement Request

Discussion in 'Data Oriented Technology Stack' started by tertle, Aug 23, 2019.

  1. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,666
    As many are aware Native[Multi]HashMap can be a bit slow to clear or instantiate when it gets large due to having to iterate 3 arrays and set all values to -1.

    Code (CSharp):
    1. public static unsafe void Clear(NativeHashMapData* data)
    2.         {
    3.             int* buckets = (int*)data->buckets;
    4.             for (int i = 0; i <= data->bucketCapacityMask; ++i)
    5.                 buckets[i] = -1;
    6.             int* nextPtrs = (int*)data->next;
    7.             for (int i = 0; i < data->keyCapacity; ++i)
    8.                 nextPtrs[i] = -1;
    9.             for (int tls = 0; tls < JobsUtility.MaxJobThreadCount; ++tls)
    10.                 data->firstFreeTLS[tls * NativeHashMapData.IntsPerCacheLine] = -1;
    11.             data->allocatedIndexLength = 0;
    12.         }
    However in 2019.3 this can be greatly improved without redesigning the hashmap by replacing this with a call to MemSet. For example (just 1 bucket, you can fill the rest in)

    Code (CSharp):
    1. #if UNITY_2019_3_OR_NEWER
    2.     UnsafeUtility.MemSet(data->buckets, byte.MaxValue, (data->bucketCapacityMask + 1) * UnsafeUtility.SizeOf<int>()); // i think it's +1 right?
    3. #else
    4.     int* buckets = (int*)data->buckets;
    5.     for (int i = 0; i <= data->bucketCapacityMask; ++i)
    6.         buckets[i] = -1;
    7. #endif
    It's 4x faster from my testing.

    upload_2019-8-23_12-5-16.png
     
    Jes28, wobes and Creepgin like this.
  2. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    102
    Memclear is about 10x faster also, but it requires changing some of the logic so 0 is default.
     
    Jes28 likes this.