ื˜ื‘ืœืช hash ืคืฉื•ื˜ื” ืขื‘ื•ืจ GPU

ื˜ื‘ืœืช hash ืคืฉื•ื˜ื” ืขื‘ื•ืจ GPU
ืคืจืกืžืชื™ ืืช ื–ื” ื‘-Github ืคืจื•ื™ืงื˜ ื—ื“ืฉ A Simple GPU Hash Table.

ื–ื•ื”ื™ ื˜ื‘ืœืช Hash ืคืฉื•ื˜ื” ืฉืœ โ€‹โ€‹GPU ื”ืžืกื•ื’ืœืช ืœืขื‘ื“ ืžืื•ืช ืžื™ืœื™ื•ื ื™ ื”ื•ืกืคื•ืช ื‘ืฉื ื™ื™ื”. ื‘ืžื—ืฉื‘ ื”ื ื™ื™ื“ NVIDIA GTX 1060 ืฉืœื™, ื”ืงื•ื“ ืžื›ื ื™ืก 64 ืžื™ืœื™ื•ืŸ ื–ื•ื’ื•ืช ืžืคืชื—-ืขืจืš ืฉื ื•ืฆืจื• ื‘ืืงืจืื™ ืชื•ืš ื›-210 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” ื•ืžืกื™ืจ 32 ืžื™ืœื™ื•ืŸ ื–ื•ื’ื•ืช ืชื•ืš ื›-64 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื”.

ื›ืœื•ืžืจ, ื”ืžื”ื™ืจื•ืช ื‘ืžื—ืฉื‘ ื ื™ื™ื“ ื”ื™ื ื›-300 ืžื™ืœื™ื•ืŸ ื”ื•ืกืคื•ืช/ืฉื ื™ื™ื” ื•-500 ืžื™ืœื™ื•ืŸ ืžื—ื™ืงื•ืช/ืฉื ื™ื™ื”.

ื”ื˜ื‘ืœื” ื›ืชื•ื‘ื” ื‘-CUDA, ืื ื›ื™ ื ื™ืชืŸ ืœื™ื™ืฉื ืืช ืื•ืชื” ื˜ื›ื ื™ืงื” ืขืœ HLSL ืื• GLSL. ืœื™ื™ืฉื•ื ืžืกืคืจ ืžื’ื‘ืœื•ืช ื›ื“ื™ ืœื”ื‘ื˜ื™ื— ื‘ื™ืฆื•ืขื™ื ื’ื‘ื•ื”ื™ื ื‘ื›ืจื˜ื™ืก ืžืกืš:

  • ืจืง ืžืคืชื—ื•ืช 32 ืกื™ื‘ื™ื•ืช ื•ืื•ืชื ืขืจื›ื™ื ืžืขื•ื‘ื“ื™ื.
  • ืœืฉื•ืœื—ืŸ ื”ืืฉ ื™ืฉ ื’ื•ื“ืœ ืงื‘ื•ืข.
  • ื•ื”ื’ื•ื“ืœ ื”ื–ื” ื—ื™ื™ื‘ ืœื”ื™ื•ืช ืฉื•ื•ื” ืœืฉื ื™ื™ื ื‘ื—ื–ืงืช.

ืขื‘ื•ืจ ืžืคืชื—ื•ืช ื•ืขืจื›ื™ื, ืขืœื™ืš ืœืฉืžื•ืจ ืกืžืŸ ืžืคืจื™ื“ ืคืฉื•ื˜ (ื‘ืงื•ื“ ืฉืœืžืขืœื” ื–ื” 0xffffffff).

ืฉื•ืœื—ืŸ ื—ืฉื™ืฉ ืœืœื ืžื ืขื•ืœื™ื

ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืžืฉืชืžืฉืช ื‘ื›ืชื•ื‘ืช ืคืชื•ื—ื” ืขื ื—ื™ื˜ื•ื˜ ืœื™ื ื™ืืจื™, ื›ืœื•ืžืจ, ื–ื” ืคืฉื•ื˜ ืžืขืจืš ืฉืœ ืฆืžื“ื™ ืžืคืชื—-ืขืจืš ืฉืžืื•ื—ืกืŸ ื‘ื–ื™ื›ืจื•ืŸ ื•ื‘ืขืœ ื‘ื™ืฆื•ืขื™ ืžื˜ืžื•ืŸ ืžืขื•ืœื™ื. ืœื ื ื™ืชืŸ ืœื•ืžืจ ืืช ืื•ืชื• ื”ื“ื‘ืจ ืœื’ื‘ื™ ืฉืจืฉื•ืจ, ื”ื›ื•ืœืœ ื—ื™ืคื•ืฉ ืžืฆื‘ื™ืข ื‘ืจืฉื™ืžื” ืžืงื•ืฉืจืช. ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘ ื”ื™ื ืžืขืจืš ืคืฉื•ื˜ ื”ืžืื—ืกืŸ ืืœืžื ื˜ื™ื KeyValue:

struct KeyValue
{
    uint32_t key;
    uint32_t value;
};

ื’ื•ื“ืœ ื”ื˜ื‘ืœื” ื”ื•ื ื—ื–ืงืช ืฉืชื™ื™ื, ืœื ืžืกืคืจ ืจืืฉื•ื ื™, ื›ื™ ืžืกืคื™ืงื” ื”ื•ืจืื” ืื—ืช ืžื”ื™ืจื” ื›ื“ื™ ืœื”ื—ื™ืœ ืืช ืžืกื›ืช pow2/AND, ืื‘ืœ ืื•ืคืจื˜ื•ืจ ื”ืžื•ื“ื•ืœื•ืก ืื™ื˜ื™ ื”ืจื‘ื” ื™ื•ืชืจ. ื–ื” ื—ืฉื•ื‘ ื‘ืžืงืจื” ืฉืœ ื‘ื“ื™ืงื” ืœื™ื ื™ืืจื™ืช, ืฉื›ืŸ ื‘ื—ื™ืคื•ืฉ ื˜ื‘ืœื” ืœื™ื ื™ืืจื™ ื™ืฉ ืœืขื˜ื•ืฃ ืืช ืื™ื ื“ืงืก ื”ืžืฉื‘ืฆื•ืช ื‘ื›ืœ ืžืฉื‘ืฆืช. ื•ื›ืชื•ืฆืื” ืžื›ืš, ืขืœื•ืช ื”ืคืขื•ืœื” ืžืชื•ื•ืกืคืช ืžื•ื“ื•ืœื• ื‘ื›ืœ ืžืฉื‘ืฆืช.

ื”ื˜ื‘ืœื” ืžืื—ืกื ืช ืจืง ืืช ื”ืžืคืชื— ื•ื”ืขืจืš ืขื‘ื•ืจ ื›ืœ ืืœืžื ื˜, ืœื ื’ื™ื‘ื•ื‘ ืฉืœ ื”ืžืคืชื—. ืžื›ื™ื•ื•ืŸ ืฉื”ื˜ื‘ืœื” ืžืื—ืกื ืช ืจืง ืžืคืชื—ื•ืช ืฉืœ 32 ืกื™ื‘ื™ื•ืช, ื”-hash ืžื—ื•ืฉื‘ ืžื”ืจ ืžืื•ื“. ื”ืงื•ื“ ืฉืœืžืขืœื” ืžืฉืชืžืฉ ื‘-Hash Murmur3, ืฉืžื‘ืฆืข ืจืง ื›ืžื” ืžืฉืžืจื•ืช, XOR ื•ื”ื›ืคืœื•ืช.

ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืžืฉืชืžืฉืช ื‘ื˜ื›ื ื™ืงื•ืช ื”ื’ื ืช ื ืขื™ืœื” ืฉืื™ื ืŸ ืชืœื•ื™ื•ืช ื‘ืกื“ืจ ื”ื–ื™ื›ืจื•ืŸ. ื’ื ืื ืคืขื•ืœื•ืช ื›ืชื™ื‘ื” ืžืกื•ื™ืžื•ืช ืžืฉื‘ืฉื•ืช ืืช ื”ืกื“ืจ ืฉืœ ืคืขื•ืœื•ืช ืื—ืจื•ืช ื›ืืœื”, ื˜ื‘ืœืช ื”-hash ืขื“ื™ื™ืŸ ืชืฉืžื•ืจ ืขืœ ื”ืžืฆื‘ ื”ื ื›ื•ืŸ. ื ื“ื‘ืจ ืขืœ ื–ื” ืœื”ืœืŸ. ื”ื˜ื›ื ื™ืงื” ืขื•ื‘ื“ืช ืžืฆื•ื™ืŸ ืขื ื›ืจื˜ื™ืกื™ ืžืกืš ืฉืžืจื™ืฆื™ื ืืœืคื™ ืฉืจืฉื•ืจื™ื ื‘ืžืงื‘ื™ืœ.

ื”ืžืคืชื—ื•ืช ื•ื”ืขืจื›ื™ื ื‘ื˜ื‘ืœืช ื”-hash ืžืื•ืชื—ืœื™ื ืœืจื™ืง.

ื ื™ืชืŸ ืœืฉื ื•ืช ืืช ื”ืงื•ื“ ื›ืš ืฉื™ื˜ืคืœ ื’ื ื‘ืžืคืชื—ื•ืช ื•ื‘ืขืจื›ื™ื ืฉืœ 64 ืกื™ื‘ื™ื•ืช. ืžืคืชื—ื•ืช ื“ื•ืจืฉื™ื ืคืขื•ืœื•ืช ืงืจื™ืื”, ื›ืชื™ื‘ื” ื•ื”ืฉื•ื•ืื”-ื”ื—ืœืคื” ืื˜ื•ืžื™ืช. ื•ืขืจื›ื™ื ื“ื•ืจืฉื™ื ืคืขื•ืœื•ืช ืงืจื™ืื” ื•ื›ืชื™ื‘ื” ืื˜ื•ืžื™ื•ืช. ืœืžืจื‘ื” ื”ืžื–ืœ, ื‘-CUDA, ืคืขื•ืœื•ืช ืงืจื™ืื”-ื›ืชื™ื‘ื” ืขื‘ื•ืจ ืขืจื›ื™ 32 ื•-64 ืกื™ื‘ื™ื•ืช ื”ืŸ ืื˜ื•ืžื™ื•ืช ื›ืœ ืขื•ื“ ื”ืŸ ืžื™ื•ืฉืจื•ืช ื‘ืื•ืคืŸ ื˜ื‘ืขื™ (ืจืื” ืœื”ืœืŸ). ื›ืืŸ), ื•ื›ืจื˜ื™ืกื™ ืžืกืš ืžื•ื“ืจื ื™ื™ื ืชื•ืžื›ื™ื ื‘ืคืขื•ืœื•ืช ื”ืฉื•ื•ืื” ื•ื”ื—ืœืคื” ืื˜ื•ืžื™ื•ืช ืฉืœ 64 ืกื™ื‘ื™ื•ืช. ื›ืžื•ื‘ืŸ, ื›ืืฉืจ ืขื•ื‘ืจื™ื ืœ-64 ืกื™ื‘ื™ื•ืช, ื”ื‘ื™ืฆื•ืขื™ื ื™ืจื“ื• ืžืขื˜.

ืžืฆื‘ ื˜ื‘ืœืช Hash

ืœื›ืœ ื–ื•ื’ ืžืคืชื—-ืขืจืš ื‘ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘ ื™ื›ื•ืœ ืœื”ื™ื•ืช ืื—ื“ ืžืืจื‘ืขื” ืžืฆื‘ื™ื:

  • ืžืคืชื— ื•ืขืจืš ืจื™ืงื™ื. ื‘ืžืฆื‘ ื–ื”, ื˜ื‘ืœืช ื”-hash ืžืื•ืชื—ืœืช.
  • ื”ืžืคืชื— ื ื›ืชื‘, ืืš ื”ืขืจืš ืขื“ื™ื™ืŸ ืœื ื ื›ืชื‘. ืื ืฉืจืฉื•ืจ ืื—ืจ ืงื•ืจื ื ืชื•ื ื™ื ื›ืขืช, ื”ื•ื ื™ื—ื–ื•ืจ ืจื™ืง. ื–ื” ื ื•ืจืžืœื™, ืื•ืชื• ื“ื‘ืจ ื”ื™ื” ืงื•ืจื” ืื ืฉืจืฉื•ืจ ืื—ืจ ืฉืœ ื‘ื™ืฆื•ืข ื”ื™ื” ืขื•ื‘ื“ ืงืฆืช ืงื•ื“ื, ื•ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ืžื‘ื ื” ื ืชื•ื ื™ื ื‘ืžืงื‘ื™ืœ.
  • ื’ื ื”ืžืคืชื— ื•ื’ื ื”ืขืจืš ื ืจืฉืžื™ื.
  • ื”ืขืจืš ื–ืžื™ืŸ ืœืฉืจืฉื•ืจื™ื ืื—ืจื™ื ืฉืœ ื‘ื™ืฆื•ืข, ืืš ื”ืžืคืชื— ืขื“ื™ื™ืŸ ืœื. ื–ื” ื™ื›ื•ืœ ืœืงืจื•ืช ืžื›ื™ื•ื•ืŸ ืฉืœืžื•ื“ืœ ื”ืชื›ื ื•ืช CUDA ื™ืฉ ืžื•ื“ืœ ื–ื™ื›ืจื•ืŸ ืžืกื•ื“ืจ ื‘ืื•ืคืŸ ืจื•ืคืฃ. ื–ื” ื ื•ืจืžืœื™; ื‘ื›ืœ ืžืงืจื”, ื”ืžืคืชื— ืขื“ื™ื™ืŸ ืจื™ืง, ื’ื ืื ื”ืขืจืš ื›ื‘ืจ ืœื ื›ืš.

ื ื™ื•ืื ืก ื—ืฉื•ื‘ ื”ื•ื ืฉื‘ืจื’ืข ืฉื”ืžืคืชื— ื ื›ืชื‘ ืœื—ืจื™ืฅ, ื”ื•ื ื›ื‘ืจ ืœื ื–ื– - ื’ื ืื ื”ืžืคืชื— ื ืžื—ืง, ื ื“ื‘ืจ ืขืœ ื›ืš ื‘ื”ืžืฉืš.

ืงื•ื“ ื˜ื‘ืœืช ื”-hash ืืคื™ืœื• ืขื•ื‘ื“ ืขื ื“ื’ืžื™ ื–ื™ื›ืจื•ืŸ ืžืกื•ื“ืจื™ื ื‘ืื•ืคืŸ ืจื•ืคืฃ, ืฉื‘ื”ื ืกื“ืจ ื”ืงืจื™ืื” ื•ื”ื›ืชื™ื‘ื” ืฉืœ ื”ื–ื™ื›ืจื•ืŸ ืื™ื ื• ื™ื“ื•ืข. ื›ืืฉืจ ืื ื• ืžืกืชื›ืœื™ื ืขืœ ื”ื›ื ืกื”, ื—ื™ืคื•ืฉ ื•ืžื—ื™ืงื” ื‘ื˜ื‘ืœืช hash, ื–ื›ื•ืจ ืฉื›ืœ ื–ื•ื’ ืžืคืชื—-ืขืจืš ื ืžืฆื ื‘ืื—ื“ ืžืืจื‘ืขืช ื”ืžืฆื‘ื™ื ืฉืชื•ืืจื• ืœืขื™ืœ.

ื”ื›ื ืกื” ืœื˜ื‘ืœืช ื’ื™ื‘ื•ื‘

ืคื•ื ืงืฆื™ื™ืช CUDA ืฉืžื›ื ื™ืกื” ืฆืžื“ื™ ืžืคืชื—-ืขืจืš ืœื˜ื‘ืœืช hash ื ืจืื™ืช ื›ืš:

void gpu_hashtable_insert(KeyValue* hashtable, uint32_t key, uint32_t value)
{
    uint32_t slot = hash(key);

    while (true)
    {
        uint32_t prev = atomicCAS(&hashtable[slot].key, kEmpty, key);
        if (prev == kEmpty || prev == key)
        {
            hashtable[slot].value = value;
            break;
        }
        slot = (slot + 1) & (kHashTableCapacity-1);
    }
}

ื›ื“ื™ ืœื”ื›ื ื™ืก ืžืคืชื—, ื”ืงื•ื“ ื—ื•ื–ืจ ื“ืจืš ืžืขืจืš ื˜ื‘ืœืช ื”-hash ื”ื—ืœ ืžื”-hash ืฉืœ ื”ืžืคืชื— ืฉื”ื•ื›ื ืก. ื›ืœ ื—ืจื™ืฅ ื‘ืžืขืจืš ืžื‘ืฆืข ืคืขื•ืœืช ื”ืฉื•ื•ืื” ื•ื”ื—ืœืคื” ืื˜ื•ืžื™ืช ื”ืžืฉื•ื•ื” ืืช ื”ืžืคืชื— ื‘ื—ืจื™ืฅ ื–ื” ืœืจื™ืง. ืื ืžื–ื•ื”ื” ืื™ ื”ืชืืžื”, ื”ืžืคืชื— ื‘ื—ืจื™ืฅ ืžืชืขื“ื›ืŸ ืขื ื”ืžืคืชื— ืฉื”ื•ื›ื ืก, ื•ืœืื—ืจ ืžื›ืŸ ืžื•ื—ื–ืจ ืžืคืชื— ื”ื—ืจื™ืฅ ื”ืžืงื•ืจื™. ืื ืžืคืชื— ืžืงื•ืจื™ ื–ื” ื”ื™ื” ืจื™ืง ืื• ืชื•ืื ืœืžืคืชื— ืฉื”ื•ื›ื ืก, ืื–ื™ ื”ืงื•ื“ ืžืฆื ื—ืจื™ืฅ ืžืชืื™ื ืœื”ื›ื ืกื” ื•ื”ื›ื ื™ืก ืืช ื”ืขืจืš ืฉื”ื•ื›ื ืก ืœื—ืจื™ืฅ.

ืื ื‘ืงืจื™ืืช ืงืจื ืœ ืื—ืช gpu_hashtable_insert() ื™ืฉื ื ืžืกืคืจ ืืœืžื ื˜ื™ื ืขื ืื•ืชื• ืžืคืชื—, ื•ืื– ื›ืœ ืื—ื“ ืžื”ืขืจื›ื™ื ืฉืœื”ื ื™ื›ื•ืœ ืœื”ื™ื›ืชื‘ ืœื—ืจื™ืฅ ื”ืžืคืชื—. ื–ื” ื ื—ืฉื‘ ื ื•ืจืžืœื™: ืื—ืช ืžื›ืชื™ื‘ืช ืขืจืš-ืžืคืชื— ื‘ืžื”ืœืš ื”ืงืจื™ืื” ืชืฆืœื™ื—, ืืš ืžื›ื™ื•ื•ืŸ ืฉื›ืœ ื–ื” ืงื•ืจื” ื‘ืžืงื‘ื™ืœ ื‘ืชื•ืš ืžืกืคืจ ืฉืจืฉื•ืจื™ื ืฉืœ ื‘ื™ืฆื•ืข, ืื™ื ื ื• ื™ื›ื•ืœื™ื ืœื—ื–ื•ืช ืื™ื–ื• ื›ืชื™ื‘ืช ื–ื™ื›ืจื•ืŸ ืชื”ื™ื” ื”ืื—ืจื•ื ื”.

ื—ื™ืคื•ืฉ ื˜ื‘ืœืช Hash

ืงื•ื“ ืœืžืคืชื—ื•ืช ื—ื™ืคื•ืฉ:

uint32_t gpu_hashtable_lookup(KeyValue* hashtable, uint32_t key)
{
        uint32_t slot = hash(key);

        while (true)
        {
            if (hashtable[slot].key == key)
            {
                return hashtable[slot].value;
            }
            if (hashtable[slot].key == kEmpty)
            {
                return kEmpty;
            }
            slot = (slot + 1) & (kHashTableCapacity - 1);
        }
}

ื›ื“ื™ ืœืžืฆื•ื ืืช ื”ืขืจืš ืฉืœ ืžืคืชื— ื”ืžืื•ื—ืกืŸ ื‘ื˜ื‘ืœื”, ืื ื• ืขื•ื‘ืจื™ื ื“ืจืš ื”ืžืขืจืš ื”ื—ืœ ืžื”-hash ืฉืœ ื”ืžืคืชื— ืฉืื ื• ืžื—ืคืฉื™ื. ื‘ื›ืœ ืžืฉื‘ืฆืช ืื ื• ื‘ื•ื“ืงื™ื ืื ื”ืžืคืชื— ื”ื•ื ื–ื” ืฉืื ื• ืžื—ืคืฉื™ื, ื•ืื ื›ืŸ, ื ื—ื–ื™ืจ ืืช ืขืจื›ื•. ืื ื• ื’ื ื‘ื•ื“ืงื™ื ืื ื”ืžืคืชื— ืจื™ืง, ื•ืื ื›ืŸ, ืื ื• ืžื‘ื˜ืœื™ื ืืช ื”ื—ื™ืคื•ืฉ.

ืื ืœื ื ื•ื›ืœ ืœืžืฆื•ื ืืช ื”ืžืคืชื—, ื”ืงื•ื“ ืžื—ื–ื™ืจ ืขืจืš ืจื™ืง.

ื ื™ืชืŸ ืœื‘ืฆืข ืืช ื›ืœ ืคืขื•ืœื•ืช ื”ื—ื™ืคื•ืฉ ื”ืœืœื• ื‘ืžืงื‘ื™ืœ ื‘ืืžืฆืขื•ืช ื”ื•ืกืคื•ืช ื•ืžื—ื™ืงื•ืช. ืœื›ืœ ื–ื•ื’ ื‘ื˜ื‘ืœื” ื™ื”ื™ื” ืื—ื“ ืžืืจื‘ืขืช ื”ืžืฆื‘ื™ื ืฉืชื•ืืจื• ืœืขื™ืœ ืขื‘ื•ืจ ื”ื–ืจื™ืžื”.

ืžื—ื™ืงื” ื‘ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘

ืงื•ื“ ืœืžื—ื™ืงืช ืžืคืชื—ื•ืช:

void gpu_hashtable_delete(KeyValue* hashtable, uint32_t key, uint32_t value)
{
    uint32_t slot = hash(key);

    while (true)
    {
        if (hashtable[slot].key == key)
        {
            hashtable[slot].value = kEmpty;
            return;
        }
        if (hashtable[slot].key == kEmpty)
        {
            return;
        }
        slot = (slot + 1) & (kHashTableCapacity - 1);
    }
}

ืžื—ื™ืงืช ืžืคืชื— ืžืชื‘ืฆืขืช ื‘ืฆื•ืจื” ื—ืจื™ื’ื”: ืื ื• ืžืฉืื™ืจื™ื ืืช ื”ืžืคืชื— ื‘ื˜ื‘ืœื” ื•ืžืกืžื ื™ื ืืช ืขืจื›ื• (ืœื ืืช ื”ืžืคืชื— ืขืฆืžื•) ื›ืจื™ืง. ืงื•ื“ ื–ื” ื“ื•ืžื” ืžืื•ื“ ืœ lookup(), ืืœื ืฉื›ืืฉืจ ื ืžืฆื ื”ืชืืžื” ืขืœ ืžืคืชื—, ื”ื•ื ื”ื•ืคืš ืืช ื”ืขืจืš ืฉืœื• ืœืจื™ืง.

ื›ืคื™ ืฉืฆื•ื™ืŸ ืœืขื™ืœ, ื‘ืจื’ืข ืฉืžืคืชื— ื ื›ืชื‘ ืœืžืฉื‘ืฆืช, ื”ื•ื ืœื ืžื•ื–ื– ื™ื•ืชืจ. ื’ื ื›ืืฉืจ ืืœืžื ื˜ ื ืžื—ืง ืžื”ื˜ื‘ืœื”, ื”ืžืคืชื— ื ืฉืืจ ื‘ืžืงื•ืžื•, ื”ืขืจืš ืฉืœื• ืคืฉื•ื˜ ื”ื•ืคืš ืจื™ืง. ื–ื” ืื•ืžืจ ืฉืื ื—ื ื• ืœื ืฆืจื™ื›ื™ื ืœื”ืฉืชืžืฉ ื‘ืคืขื•ืœืช ื›ืชื™ื‘ื” ืื˜ื•ืžื™ืช ืœืขืจืš ื”ื—ืจื™ืฅ, ื›ื™ ื–ื” ืœื ืžืฉื ื” ืื ื”ืขืจืš ื”ื ื•ื›ื—ื™ ืจื™ืง ืื• ืœื - ื”ื•ื ืขื“ื™ื™ืŸ ื™ื”ืคื•ืš ืœืจื™ืง.

ืฉื™ื ื•ื™ ื’ื•ื“ืœ ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘

ื ื™ืชืŸ ืœืฉื ื•ืช ืืช ื”ื’ื•ื“ืœ ืฉืœ ื˜ื‘ืœืช hash ืขืœ ื™ื“ื™ ื™ืฆื™ืจืช ื˜ื‘ืœื” ื’ื“ื•ืœื” ื™ื•ืชืจ ื•ื”ื›ื ืกืช ืืœืžื ื˜ื™ื ืœื ืจื™ืงื™ื ืžื”ื˜ื‘ืœื” ื”ื™ืฉื ื” ืœืชื•ื›ื”. ืœื ื™ื™ืฉืžืชื™ ืืช ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ื”ื–ื• ื›ื™ ืจืฆื™ืชื™ ืœืฉืžื•ืจ ืขืœ ืงื•ื“ ืœื“ื•ื’ืžื” ืคืฉื•ื˜. ื™ืชืจื” ืžื›ืš, ื‘ืชื•ื›ื ื™ื•ืช CUDA, ื”ืงืฆืืช ื–ื™ื›ืจื•ืŸ ื ืขืฉื™ืช ืœืจื•ื‘ ื‘ืงื•ื“ ื”ืžืืจื— ื•ืœื ื‘ืœื™ื‘ืช CUDA.

ื”ืžืืžืจ ื˜ื‘ืœืช Hash ืœืœื ื ืขื™ืœื” ืœืœื ื”ืžืชื ื” ืžืชืืจ ื›ื™ืฆื“ ืœืฉื ื•ืช ืžื‘ื ื” ื ืชื•ื ื™ื ื›ื–ื” ืžื•ื’ืŸ ื ืขื™ืœื”.

ืชื—ืจื•ืชื™ื•ืช

ื‘ืงื˜ืขื™ ื”ืงื•ื“ ืฉืœ ื”ืคื•ื ืงืฆื™ื” ืœืขื™ืœ gpu_hashtable_insert(), _lookup() ะธ _delete() ืœืขื‘ื“ ื–ื•ื’ ืžืคืชื—-ืขืจืš ืื—ื“ ื‘ื›ืœ ืคืขื. ื•ืžื˜ื” gpu_hashtable_insert(), _lookup() ะธ _delete() ืœืขื‘ื“ ืžืขืจืš ืฉืœ ื–ื•ื’ื•ืช ื‘ืžืงื‘ื™ืœ, ื›ืœ ื–ื•ื’ ื‘ืฉืจืฉื•ืจ ื‘ื™ืฆื•ืข GPU ื ืคืจื“:

// CPU code to invoke the CUDA kernel on the GPU
uint32_t threadblocksize = 1024;
uint32_t gridsize = (numkvs + threadblocksize - 1) / threadblocksize;
gpu_hashtable_insert_kernel<<<gridsize, threadblocksize>>>(hashtable, kvs, numkvs);

// GPU code to process numkvs key/values in parallel
void gpu_hashtable_insert_kernel(KeyValue* hashtable, const KeyValue* kvs, unsigned int numkvs)
{
    unsigned int threadid = blockIdx.x*blockDim.x + threadIdx.x;
    if (threadid < numkvs)
    {
        gpu_hashtable_insert(hashtable, kvs[threadid].key, kvs[threadid].value);
    }
}

ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืขืžื™ื“ื” ืœื ืขื™ืœื” ืชื•ืžื›ืช ื‘ื”ื•ืกืคื•ืช, ื—ื™ืคื•ืฉื™ื ื•ืžื—ื™ืงื•ืช ื‘ืžืงื‘ื™ืœ. ืžื›ื™ื•ื•ืŸ ืฉืฆืžื“ื™ ืžืคืชื—-ืขืจืš ื ืžืฆืื™ื ืชืžื™ื“ ื‘ืื—ื“ ืžืืจื‘ืขื” ืžืฆื‘ื™ื ื•ื”ืžืคืชื—ื•ืช ืื™ื ื ื–ื–ื™ื, ื”ื˜ื‘ืœื” ืžื‘ื˜ื™ื—ื” ื ื›ื•ื ื•ืช ื’ื ื›ืืฉืจ ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืกื•ื’ื™ื ืฉื•ื ื™ื ืฉืœ ืคืขื•ืœื•ืช ื‘ื•-ื–ืžื ื™ืช.

ืขื ื–ืืช, ืื ื ืขื‘ื“ ืืฆื•ื•ื” ืฉืœ ื”ื•ืกืคื•ืช ื•ืžื—ื™ืงื•ืช ื‘ืžืงื‘ื™ืœ, ื•ืื ืžืขืจืš ื”ืงืœื˜ ืฉืœ ื”ื–ื•ื’ื•ืช ืžื›ื™ืœ ืžืคืชื—ื•ืช ื›ืคื•ืœื™ื, ืื– ืœื ื ื•ื›ืœ ืœื—ื–ื•ืช ืื™ืœื• ื–ื•ื’ื•ืช "ื™ื–ื›ื•" - ื™ื™ื›ืชื‘ื• ืื—ืจื•ืŸ ืœื˜ื‘ืœืช ื”-hash. ื ื ื™ื— ืฉืงืจืื ื• ืœืงื•ื“ ื”ื”ื›ื ืกื” ืขื ืžืขืจืš ืงืœื˜ ืฉืœ ื–ื•ื’ื•ืช A/0 B/1 A/2 C/3 A/4. ื›ืืฉืจ ื”ืงื•ื“ ืžืกืชื™ื™ื, ื–ื•ื’ื•ืช B/1 ะธ C/3 ืžื•ื‘ื˜ื— ืœื”ื™ื•ืช ื ื•ื›ื—ื™ื ื‘ื˜ื‘ืœื”, ืืš ื‘ืžืงื‘ื™ืœ ื›ืœ ืื—ื“ ืžื”ื–ื•ื’ื•ืช ื™ื•ืคื™ืข ื‘ื” A/0, A/2 ืื• A/4. ื–ื• ื™ื›ื•ืœื” ืœื”ื™ื•ืช ื‘ืขื™ื” ืื• ืœื - ื”ื›ืœ ืชืœื•ื™ ื‘ืืคืœื™ืงืฆื™ื”. ื™ื™ืชื›ืŸ ืฉืชื“ืข ืžืจืืฉ ืฉืื™ืŸ ืžืคืชื—ื•ืช ื›ืคื•ืœื™ื ื‘ืžืขืจืš ื”ืงืœื˜, ืื• ืฉืœื ืื›ืคืช ืœืš ืื™ื–ื” ืขืจืš ื ื›ืชื‘ ืื—ืจื•ืŸ.

ืื ื–ื• ื‘ืขื™ื” ืขื‘ื•ืจืš, ืขืœื™ืš ืœื”ืคืจื™ื“ ืืช ื”ื–ื•ื’ื•ืช ื”ื›ืคื•ืœื™ื ืœืงืจื™ืื•ืช ืžืขืจื›ืช CUDA ืฉื•ื ื•ืช. ื‘-CUDA, ื›ืœ ืคืขื•ืœื” ืฉืงื•ืจืืช ืœืงืจื ืœ ืชืžื™ื“ ืžืกืชื™ื™ืžืช ืœืคื ื™ ืงืจื™ืืช ื”ืงืจื ืœ ื”ื‘ืื” (ืœืคื—ื•ืช ื‘ืชื•ืš ืฉืจืฉื•ืจ ืื—ื“. ื‘ืฉืจืฉื•ืจื™ื ืฉื•ื ื™ื, ื”ื’ืจืขื™ื ื™ื ืžื‘ื•ืฆืขื™ื ื‘ืžืงื‘ื™ืœ). ื‘ื“ื•ื’ืžื” ืœืžืขืœื”, ืื ืืชื” ืงื•ืจื ืœื™ื‘ื” ืื—ืช ืขื A/0 B/1 A/2 C/3, ื•ื”ืฉื ื™ ืขื A/4, ื•ืื– ื”ืžืคืชื— A ื™ืงื‘ืœ ืืช ื”ืขืจืš 4.

ืขื›ืฉื™ื• ื‘ื•ืื• ื ื“ื‘ืจ ืขืœ ื”ืื ืคื•ื ืงืฆื™ื•ืช ืฆืจื™ืš lookup() ะธ delete() ื”ืฉืชืžืฉ ื‘ืžืฆื‘ื™ืข ืจื’ื™ืœ ืื• ื ื“ื™ืฃ ืœืžืขืจืš ืฉืœ ื–ื•ื’ื•ืช ื‘ื˜ื‘ืœืช ื”-hash. ืชื™ืขื•ื“ CUDA ืžืฆื™ื™ืŸ ืฉ:

ื”ืžื”ื“ืจ ืขืฉื•ื™ ืœื‘ื—ื•ืจ ืœื‘ืฆืข ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ืฉืœ ืงืจื™ืื” ื•ื›ืชื™ื‘ื” ืœื–ื™ื›ืจื•ืŸ ื’ืœื•ื‘ืœื™ ืื• ืžืฉื•ืชืฃ... ื ื™ืชืŸ ืœื”ืฉื‘ื™ืช ืื•ืคื˜ื™ืžื™ื–ืฆื™ื•ืช ืืœื• ื‘ืืžืฆืขื•ืช ืžื™ืœืช ื”ืžืคืชื— volatile: ... ื›ืœ ื”ืชื™ื™ื—ืกื•ืช ืœืžืฉืชื ื” ื–ื” ืžื•ืจื›ื‘ืช ืœื”ื•ืจืืช ืงืจื™ืื” ืื• ื›ืชื™ื‘ื” ื‘ื–ื™ื›ืจื•ืŸ ืืžื™ืชื™.

ืฉื™ืงื•ืœื™ ืชืงื™ื ื•ืช ืื™ื ื ืžื—ื™ื™ื‘ื™ื ื™ื™ืฉื•ื volatile. ืื ืฉืจืฉื•ืจ ื”ื‘ื™ืฆื•ืข ืžืฉืชืžืฉ ื‘ืขืจืš ืฉืžื•ืจ ืžืคืขื•ืœืช ืงืจื™ืื” ืงื•ื“ืžืช, ืื– ื”ื•ื ื™ืฉืชืžืฉ ื‘ืžื™ื“ืข ืžืขื˜ ืžื™ื•ืฉืŸ. ืื‘ืœ ืขื“ื™ื™ืŸ, ื–ื”ื• ืžื™ื“ืข ืžื”ืžืฆื‘ ื”ื ื›ื•ืŸ ืฉืœ ื˜ื‘ืœืช ื”-hash ื‘ืจื’ืข ืžืกื•ื™ื ืฉืœ ืงืจื™ืืช ื”ืงืจื ืœ. ืื ืืชื” ืฆืจื™ืš ืœื”ืฉืชืžืฉ ื‘ืžื™ื“ืข ื”ืขื“ื›ื ื™ ื‘ื™ื•ืชืจ, ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืื™ื ื“ืงืก volatile, ืื‘ืœ ืื– ื”ื‘ื™ืฆื•ืขื™ื ื™ืจื“ื• ืžืขื˜: ืœืคื™ ื”ื‘ื“ื™ืงื•ืช ืฉืœื™, ื‘ืขืช ืžื—ื™ืงืช 32 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื, ื”ืžื”ื™ืจื•ืช ื™ืจื“ื” ืž-500 ืžื™ืœื™ื•ืŸ ืžื—ื™ืงื•ืช/ืฉื ื™ื™ื” ืœ-450 ืžื™ืœื™ื•ืŸ ืžื—ื™ืงื•ืช/ืฉื ื™ื™ื”.

ืคืจื•ื“ื•ืงื˜ื™ื‘ื™ื•ืช

ื‘ืžื‘ื—ืŸ ืœื”ื›ื ืกืช 64 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื ื•ืžื—ื™ืงืช 32 ืžื™ืœื™ื•ืŸ ืžื”ื, ืชื—ืจื•ืช ื‘ื™ืŸ std::unordered_map ื•ืื™ืŸ ื›ืžืขื˜ ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘ ืขื‘ื•ืจ ื”-GPU:

ื˜ื‘ืœืช hash ืคืฉื•ื˜ื” ืขื‘ื•ืจ GPU
std::unordered_map ื‘ื™ืœื” 70 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” ื‘ื”ื›ื ืกื” ื•ื”ืกืจื” ืฉืœ ืืœืžื ื˜ื™ื ื•ืœืื—ืจ ืžื›ืŸ ื‘ืฉื—ืจื•ืจื unordered_map (ืœื”ื™ืคื˜ืจ ืžืžื™ืœื™ื•ื ื™ ืืœืžื ื˜ื™ื ืœื•ืงื— ื”ืจื‘ื” ื–ืžืŸ, ื›ื™ ื‘ืคื ื™ื unordered_map ืžืชื‘ืฆืขื•ืช ื”ืงืฆืื•ืช ื–ื™ื›ืจื•ืŸ ืžืจื•ื‘ื•ืช). ื‘ื›ื ื•ืช, std:unordered_map ื”ื’ื‘ืœื•ืช ืฉื•ื ื•ืช ืœื—ืœื•ื˜ื™ืŸ. ื–ื”ื• ื—ื•ื˜ ื”ืคืขืœื” ื™ื—ื™ื“ ืฉืœ ืžืขื‘ื“, ืชื•ืžืš ื‘ืขืจื›ื™ ืžืคืชื— ื‘ื›ืœ ื’ื•ื“ืœ, ืžืชืคืงื“ ื”ื™ื˜ื‘ ื‘ืฉื™ืขื•ืจื™ ื ื™ืฆื•ืœ ื’ื‘ื•ื”ื™ื ื•ืžืฆื™ื’ ื‘ื™ืฆื•ืขื™ื ื™ืฆื™ื‘ื™ื ืœืื—ืจ ืžื—ื™ืงื•ืช ืžืจื•ื‘ื•ืช.

ืžืฉืš ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืขื‘ื•ืจ ื”-GPU ื•ื”ืชืงืฉื•ืจืช ื‘ื™ืŸ ืชื•ื›ื ื™ื•ืช ื”ื™ื™ืชื” 984 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื”. ื–ื” ื›ื•ืœืœ ืืช ื”ื–ืžืŸ ื”ืžื•ืฉืงืข ื‘ื”ืฆื‘ืช ื”ื˜ื‘ืœื” ื‘ื–ื™ื›ืจื•ืŸ ื•ืžื—ื™ืงืชื” (ื”ืงืฆืืช 1 ื’'ื™ื’ื”-ื‘ื™ื™ื˜ ืฉืœ ื–ื™ื›ืจื•ืŸ ืคืขื ืื—ืช, ืžื” ืฉืœื•ืงื— ื–ืžืŸ ืžื” ื‘-CUDA), ื”ื›ื ืกืช ื•ืžื—ื™ืงืช ืืœืžื ื˜ื™ื ื•ืื™ื˜ืจืฆื™ื” ืขืœื™ื”ื. ื›ืœ ื”ืขื•ืชืงื™ื ืžื–ื™ื›ืจื•ืŸ ื›ืจื˜ื™ืก ื”ืžืกืš ื•ืžืžื ื• ื ืœืงื—ื™ื ื‘ื—ืฉื‘ื•ืŸ ื’ื ื›ืŸ.

ืœื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืขืฆืžื” ื ื“ืจืฉื• 271 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” ื›ื“ื™ ืœื”ืฉืœื™ื. ื–ื” ื›ื•ืœืœ ืืช ื”ื–ืžืŸ ื”ืžื•ืฉืงืข ืขืœ ื™ื“ื™ ื›ืจื˜ื™ืก ื”ืžืกืš ื‘ื”ื›ื ืกืช ื•ืžื—ื™ืงืช ืืœืžื ื˜ื™ื, ื•ืื™ื ื• ืœื•ืงื— ื‘ื—ืฉื‘ื•ืŸ ืืช ื”ื–ืžืŸ ื”ืžื•ืฉืงืข ื‘ื”ืขืชืงื” ืœื–ื™ื›ืจื•ืŸ ื•ืื™ื˜ืจืฆื™ื” ืขืœ ื”ื˜ื‘ืœื” ื”ืžืชืงื‘ืœืช. ืื ื˜ื‘ืœืช ื”-GPU ืงื™ื™ืžืช ืœืื•ืจืš ื–ืžืŸ, ืื• ืื ื˜ื‘ืœืช ื”-hash ื›ืœื•ืœื” ื‘ื–ื™ื›ืจื•ืŸ ืฉืœ ื›ืจื˜ื™ืก ื”ืžืกืš (ืœื“ื•ื’ืžื”, ื›ื“ื™ ืœื™ืฆื•ืจ ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘ ืฉืชืฉืžืฉ ืืช ืงื•ื“ ื”-GPU ืื—ืจ ื•ืœื ืืช ื”ืžืขื‘ื“ ื”ืžืจื›ื–ื™), ืื– ืชื•ืฆืืช ื”ื‘ื“ื™ืงื” ืจืœื•ื•ื ื˜ื™ืช.

ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ืœื›ืจื˜ื™ืก ืžืกืš ืžื“ื’ื™ืžื” ื‘ื™ืฆื•ืขื™ื ื’ื‘ื•ื”ื™ื ื”ื•ื“ื•ืช ืœืชืคื•ืงื” ื’ื‘ื•ื”ื” ื•ื”ืงื‘ืœื” ืืงื˜ื™ื‘ื™ืช.

ืžื’ื‘ืœื•ืช

ืœืืจื›ื™ื˜ืงื˜ื•ืจืช ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ื™ืฉ ื›ืžื” ื‘ืขื™ื•ืช ืฉื›ื“ืื™ ืœืฉื™ื ืœื‘ ืืœื™ื”ืŸ:

  • ื—ื™ื˜ื•ื˜ ืœื™ื ื™ืืจื™ ื ืคื’ืข ืขืœ ื™ื“ื™ clustering, ืžื” ืฉื’ื•ืจื ืœืžืคืชื—ื•ืช ื‘ื˜ื‘ืœื” ืœื”ื™ื•ืช ืคื—ื•ืช ืžืžื•ืฉืœื.
  • ืžืคืชื—ื•ืช ืื™ื ื ืžื•ืกืจื™ื ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” delete ื•ืขื ื”ื–ืžืŸ ื”ื ืขื•ืžืกื™ื ืืช ื”ืฉื•ืœื—ืŸ.

ื›ืชื•ืฆืื” ืžื›ืš, ื”ื‘ื™ืฆื•ืขื™ื ืฉืœ ื˜ื‘ืœืช ื’ื™ื‘ื•ื‘ ืขืœื•ืœื™ื ืœื”ืชื“ืจื“ืจ ื‘ื”ื“ืจื’ื”, ื‘ืžื™ื•ื—ื“ ืื ื”ื™ื ืงื™ื™ืžืช ื‘ืžืฉืš ื–ืžืŸ ืจื‘ ื•ื™ืฉ ืœื” ื”ื•ืกืคื•ืช ื•ืžื—ื™ืงื•ืช ืจื‘ื•ืช. ืื—ืช ื”ื“ืจื›ื™ื ืœืฆืžืฆื ืืช ื”ื—ืกืจื•ื ื•ืช ื”ืœืœื• ื”ื™ื ืœื”ื›ื ื™ืก ืžื—ื“ืฉ ืœื˜ื‘ืœื” ื—ื“ืฉื” ืขื ืฉื™ืขื•ืจ ื ื™ืฆื•ืœ ื ืžื•ืš ืœืžื“ื™ ื•ืœืกื ืŸ ืืช ื”ืžืคืชื—ื•ืช ืฉื”ื•ืกืจื• ื‘ืžื”ืœืš ื”ื’ื™ื‘ื•ืฉ ืžื—ื“ืฉ.

ื›ื“ื™ ืœื”ืžื—ื™ืฉ ืืช ื”ื‘ืขื™ื•ืช ื”ืžืชื•ืืจื•ืช, ืืฉืชืžืฉ ื‘ืงื•ื“ ืฉืœืžืขืœื” ื›ื“ื™ ืœื™ืฆื•ืจ ื˜ื‘ืœื” ืขื 128 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื ื•ืœืขื‘ื•ืจ ื‘ืœื•ืœืื” ืฉืœ 4 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื ืขื“ ืฉืืžืœื 124 ืžื™ืœื™ื•ืŸ ืžืฉื‘ืฆื•ืช (ืฉื™ืขื•ืจ ื ื™ืฆื•ืœ ืฉืœ ื‘ืขืจืš 0,96). ื”ื ื” ื˜ื‘ืœืช ื”ืชื•ืฆืื•ืช, ื›ืœ ืฉื•ืจื” ื”ื™ื ืงืจื™ืืช ืœื™ื‘ืช CUDA ืœื”ื›ื ืกืช 4 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื ื—ื“ืฉื™ื ืœื˜ื‘ืœืช hash ืื—ืช:

ืฉื™ืขื•ืจ ืฉื™ืžื•ืฉ
ืžืฉืš ื”ื›ื ืกื” 4 ืืœืžื ื˜ื™ื

0,00
11,608448 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (361,314798 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,03
11,751424 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (356,918799 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,06
11,942592 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (351,205515 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,09
12,081120 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (347,178429 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,12
12,242560 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (342,600233 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,16
12,396448 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (338,347235 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,19
12,533024 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (334,660176 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,22
12,703328 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (330,173626 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,25
12,884512 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (325,530693 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,28
13,033472 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (321,810182 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,31
13,239296 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (316,807174 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,34
13,392448 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (313,184256 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,37
13,624000 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (307,861434 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,41
13,875520 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (302,280855 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,44
14,126528 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (296,909756 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,47
14,399328 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (291,284699 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,50
14,690304 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (285,515123 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,53
15,039136 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (278,892623 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,56
15,478656 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (270,973402 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,59
15,985664 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (262,379092 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,62
16,668673 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (251,627968 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,66
17,587200 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (238,486174 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,69
18,690048 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (224,413765 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,72
20,278816 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (206,831789 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,75
22,545408 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (186,038058 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,78
26,053312 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (160,989275 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,81
31,895008 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (131,503463 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,84
42,103294 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (99,619378 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,87
61,849056 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (67,815164 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,90
105,695999 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (39,682713 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

0,94
240,204636 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื” (17,461378 ืžื™ืœื™ื•ืŸ ืžืคืชื—ื•ืช/ืฉื ื™ื™ื”)

ื›ื›ืœ ืฉื”ื ื™ืฆื•ืœ ืขื•ืœื”, ื”ื‘ื™ืฆื•ืขื™ื ื™ื•ืจื“ื™ื. ื–ื” ืœื ืจืฆื•ื™ ื‘ืจื•ื‘ ื”ืžืงืจื™ื. ืื ื™ื™ืฉื•ื ืžื›ื ื™ืก ืืœืžื ื˜ื™ื ืœื˜ื‘ืœื” ื•ืื– ืžืฉืœื™ืš ืื•ืชื (ืœื“ื•ื’ืžื”, ื‘ืขืช ืกืคื™ืจืช ืžื™ืœื™ื ื‘ืกืคืจ), ื–ื• ืœื ื‘ืขื™ื”. ืื‘ืœ ืื ื”ืืคืœื™ืงืฆื™ื” ืžืฉืชืžืฉืช ื‘ื˜ื‘ืœืช hash ืืจื•ื›ืช ื—ื™ื™ื (ืœื“ื•ื’ืžื”, ื‘ืขื•ืจืš ื’ืจืคื™ ื›ื“ื™ ืœืื—ืกืŸ ื—ืœืงื™ื ืœื ืจื™ืงื™ื ืฉืœ ืชืžื•ื ื•ืช ืฉื‘ื”ื ื”ืžืฉืชืžืฉ ืžื•ืกื™ืฃ ื•ืžื•ื—ืง ืžื™ื“ืข ืœืขืชื™ื ืงืจื•ื‘ื•ืช), ืื– ื”ืชื ื”ื’ื•ืช ื–ื• ืขืœื•ืœื” ืœื”ื™ื•ืช ื‘ืขื™ื™ืชื™ืช.

ื•ืžื“ื“ ืืช ืขื•ืžืง ื”ื—ื™ื˜ื•ื˜ ืฉืœ ื˜ื‘ืœืช ื”-hash ืœืื—ืจ 64 ืžื™ืœื™ื•ืŸ ื”ื•ืกืคื•ืช (ืžืงื“ื ื ื™ืฆื•ืœ 0,5). ื”ืขื•ืžืง ื”ืžืžื•ืฆืข ื”ื™ื” 0,4774, ื›ืš ืฉืจื•ื‘ ื”ืžืงืฉื™ื ื”ื™ื• ื‘ื—ืจื™ืฅ ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ ื”ืืคืฉืจื™ ืื• ื—ืจื™ืฅ ืื—ื“ ืžื”ืžื™ืงื•ื ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ. ืขื•ืžืง ื”ืฆืœื™ืœ ื”ืžืจื‘ื™ ื”ื™ื” 60.

ืœืื—ืจ ืžื›ืŸ ืžื“ื“ืชื™ ืืช ืขื•ืžืง ื”ื—ื™ื˜ื•ื˜ ื‘ื˜ื‘ืœื” ืขื 124 ืžื™ืœื™ื•ืŸ ืชื•ืกืคื•ืช (ืžืงื“ื ื ื™ืฆื•ืœ 0,97). ื”ืขื•ืžืง ื”ืžืžื•ืฆืข ื”ื™ื” ื›ื‘ืจ 10,1757, ื•ื”ืžืงืกื™ืžื•ื - 6474 (!!). ื‘ื™ืฆื•ืขื™ ื”ื—ื™ืฉื” ืœื™ื ื™ืืจื™ื™ื ื™ื•ืจื“ื™ื ืžืฉืžืขื•ืชื™ืช ื‘ืฉื™ืขื•ืจื™ ื ื™ืฆื•ืœ ื’ื‘ื•ื”ื™ื.

ืขื“ื™ืฃ ืœืฉืžื•ืจ ืืช ืฉื™ืขื•ืจ ื”ื ื™ืฆื•ืœ ืฉืœ ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ื”ื–ื• ื ืžื•ืš. ืื‘ืœ ืื– ืื ื—ื ื• ืžื’ื“ื™ืœื™ื ืืช ื”ื‘ื™ืฆื•ืขื™ื ืขืœ ื—ืฉื‘ื•ืŸ ืฆืจื™ื›ืช ื”ื–ื™ื›ืจื•ืŸ. ืœืžืจื‘ื” ื”ืžื–ืœ, ื‘ืžืงืจื” ืฉืœ ืžืคืชื—ื•ืช ื•ืขืจื›ื™ื ืฉืœ 32 ืกื™ื‘ื™ื•ืช, ื ื™ืชืŸ ืœื”ืฆื“ื™ืง ื–ืืช. ืื ื‘ื“ื•ื’ืžื” ืœืขื™ืœ, ื‘ื˜ื‘ืœื” ืขื 128 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื, ื ืฉืžืจ ืืช ืžืงื“ื ื”ื ื™ืฆื•ืœ ืฉืœ 0,25, ืื– ื ื•ื›ืœ ืœื”ืฆื™ื‘ ื‘ื” ืœื ื™ื•ืชืจ ืž-32 ืžื™ืœื™ื•ืŸ ืืœืžื ื˜ื™ื, ื•ืฉืืจ 96 ืžื™ืœื™ื•ืŸ ื”ืžืฉื‘ืฆื•ืช ื™ืื‘ื“ื• - 8 ื‘ืชื™ื ืœื›ืœ ื–ื•ื’ , 768 ืžื’ื”-ื‘ื™ื™ื˜ ืฉืœ ื–ื™ื›ืจื•ืŸ ืฉืื‘ื“.

ืฉื™ืžื• ืœื‘ ืฉืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ืื•ื‘ื“ืŸ ื–ื™ื›ืจื•ืŸ ื›ืจื˜ื™ืก ืžืกืš, ืฉื”ื•ื ืžืฉืื‘ ื™ืงืจ ื™ื•ืชืจ ืžื–ื™ื›ืจื•ืŸ ื”ืžืขืจื›ืช. ืœืžืจื•ืช ืฉืœืจื•ื‘ ื›ืจื˜ื™ืกื™ ื”ื’ืจืคื™ืงื” ื”ืฉื•ืœื—ื ื™ื™ื ื”ืžื•ื“ืจื ื™ื™ื ื”ืชื•ืžื›ื™ื ื‘-CUDA ื™ืฉ ืœืคื—ื•ืช 4 ื’'ื™ื’ื”-ื‘ื™ื™ื˜ ืฉืœ ื–ื™ื›ืจื•ืŸ (ื‘ื–ืžืŸ ื›ืชื™ื‘ืช ืฉื•ืจื•ืช ืืœื”, ืœ-NVIDIA 2080 Ti ื™ืฉ 11 ื’'ื™ื’ื”-ื‘ื™ื™ื˜), ื–ื• ืขื“ื™ื™ืŸ ืœื ืชื”ื™ื” ื”ื”ื—ืœื˜ื” ื”ื—ื›ืžื” ืœื”ืคืกื™ื“ ื›ืžื•ื™ื•ืช ื›ืืœื”.

ื‘ื”ืžืฉืš ืื›ืชื•ื‘ ืขื•ื“ ืขืœ ื™ืฆื™ืจืช ื˜ื‘ืœืื•ืช ื’ื™ื‘ื•ื‘ ืœื›ืจื˜ื™ืกื™ ืžืกืš ืฉืื™ืŸ ืœื”ื ื‘ืขื™ื•ืช ืขื ืขื•ืžืง ื”ื—ื™ื˜ื•ื˜, ื›ืžื• ื’ื ื“ืจื›ื™ื ืœืฉื™ืžื•ืฉ ื—ื•ื–ืจ ื‘ื—ืจื™ืฆื™ื ืฉื ืžื—ืงื•.

ืžื“ื™ื“ืช ืขื•ืžืง ืฆืœื™ืœื™ื

ื›ื“ื™ ืœืงื‘ื•ืข ืืช ืขื•ืžืง ื”ื‘ื“ื™ืงื” ืฉืœ ืžืคืชื—, ื ื•ื›ืœ ืœื—ืœืฅ ืืช ื”-hash ืฉืœ ื”ืžืคืชื— (ืื™ื ื“ืงืก ื”ื˜ื‘ืœื” ื”ืื™ื“ื™ืืœื™ ืฉืœื•) ืžืื™ื ื“ืงืก ื”ื˜ื‘ืœื” ื”ืืžื™ืชื™ ืฉืœื•:

// get_key_index() -> index of key in hash table
uint32_t probelength = (get_key_index(key) - hash(key)) & (hashtablecapacity-1);

ื‘ื’ืœืœ ื”ืงืกื ืฉืœ ื”ืžืกืคืจื™ื ื”ื‘ื™ื ืืจื™ื™ื ื”ืžืฉืœื™ืžื™ื ืฉืœ ืฉื ื™ื™ื ื•ื”ืขื•ื‘ื“ื” ืฉื”ืงื™ื‘ื•ืœืช ืฉืœ ื˜ื‘ืœืช ื”ื’ื™ื‘ื•ื‘ ื”ื™ื ืฉืชื™ื™ื ื‘ื—ื–ืงืช ืฉืชื™ื™ื, ื’ื™ืฉื” ื–ื• ืชืขื‘ื•ื“ ื’ื ื›ืืฉืจ ืื™ื ื“ืงืก ื”ืžืคืชื— ื™ื•ืขื‘ืจ ืœืชื—ื™ืœืช ื”ื˜ื‘ืœื”. ื‘ื•ื ื ื™ืงื— ืžืคืชื— ืฉื’ื™ื‘ืฉ ืœ-1, ืื‘ืœ ืžื•ื›ื ืก ืœื—ืจื™ืฅ 3. ื•ืื– ืขื‘ื•ืจ ืฉื•ืœื—ืŸ ืขื ืงื™ื‘ื•ืœืช 4 ื ืงื‘ืœ (3 โ€” 1) & 3, ืฉื–ื” ืฉื•ื•ื” ืขืจืš ืœ-2.

ืžืกืงื ื”

ืื ื™ืฉ ืœืš ืฉืืœื•ืช ืื• ื”ืขืจื•ืช, ืื ื ืฉืœื— ืœื™ ืžื™ื™ืœ ืœื›ืชื•ื‘ืช ื˜ื•ื™ื˜ืจ ืื• ืœืคืชื•ื— ื ื•ืฉื ื—ื“ืฉ ื‘ ืžืื’ืจื™ื.

ืงื•ื“ ื–ื” ื ื›ืชื‘ ื‘ื”ืฉืจืืช ืžืืžืจื™ื ืžืฆื•ื™ื ื™ื:

ื‘ืขืชื™ื“, ืืžืฉื™ืš ืœื›ืชื•ื‘ ืขืœ ื™ื™ืฉื•ืžื™ ื˜ื‘ืœืช hash ืขื‘ื•ืจ ื›ืจื˜ื™ืกื™ ืžืกืš ื•ืื ืชื— ืืช ื”ื‘ื™ืฆื•ืขื™ื ืฉืœื”ื. ื”ืชื•ื›ื ื™ื•ืช ืฉืœื™ ื›ื•ืœืœื•ืช ืฉืจืฉื•ืจ, ื’ื™ื‘ื•ื‘ ืจื•ื‘ื™ืŸ ื”ื•ื“ ื•ื’ื™ื‘ื•ื‘ ืงื•ืงื™ื™ื” ื‘ืืžืฆืขื•ืช ืคืขื•ืœื•ืช ืื˜ื•ืžื™ื•ืช ื‘ืžื‘ื ื™ ื ืชื•ื ื™ื ื™ื“ื™ื“ื•ืชื™ื™ื ืœ-GPU.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”