ΠŸΡ€ΠΎΡΡ‚Π°Ρ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° для GPU

ΠŸΡ€ΠΎΡΡ‚Π°Ρ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° для GPU
Π― Π²Ρ‹Π»ΠΎΠΆΠΈΠ» Π½Π° Github Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ A Simple GPU Hash Table.

Π­Ρ‚ΠΎ простая Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° для GPU, способная ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π² сСкунду сотни ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠ² вставок. На ΠΌΠΎΡ‘ΠΌ Π½ΠΎΡƒΡ‚Π±ΡƒΠΊΠ΅ с NVIDIA GTX 1060 ΠΊΠΎΠ΄ вставляСт 64 ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Π° случайно сгСнСрированных ΠΏΠ°Ρ€ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π·Π° 210 мс ΠΈ удаляСт 32 ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Π° ΠΏΠ°Ρ€ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π·Π° 64 мс.

Π’ΠΎ Π΅ΡΡ‚ΡŒ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Π½Π° Π½ΠΎΡƒΡ‚Π±ΡƒΠΊΠ΅ составляСт ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 300 ΠΌΠ»Π½ вставок/сСк ΠΈ 500 ΠΌΠ»Π½ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ/сСк.

Π’Π°Π±Π»ΠΈΡ†Π° написана Π½Π° CUDA, хотя Ρ‚Ρƒ ΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊ HLSL ΠΈΠ»ΠΈ GLSL. Π£ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΅ΡΡ‚ΡŒ нСсколько ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… Π²Ρ‹ΡΠΎΠΊΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅:

  • ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 32-Π±ΠΈΡ‚Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΈ Ρ‚Π°ΠΊΠΈΠ΅ ΠΆΠ΅ значСния.
  • Π₯эш-Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΈΠΌΠ΅Π΅Ρ‚ фиксированный Ρ€Π°Π·ΠΌΠ΅Ρ€.
  • И этот Ρ€Π°Π·ΠΌΠ΅Ρ€ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π΅Π½ Π΄Π²ΡƒΠΌ Π² стСпСни.

Для ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ простой Ρ€Π°Π·Π³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ (Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ это 0xffffffff).

Π₯эш-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ

Π’ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ открытая адрСсация с Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΌ Π·ΠΎΠ½Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ это просто массив ΠΏΠ°Ρ€ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ хранится Π² памяти ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€Π΅Π²ΠΎΡΡ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ кэша. Π­Ρ‚ΠΎΠ³ΠΎ Π½Π΅ скаТСшь ΠΎ связывании Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ (chaining), Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ поиск указатСля Π² связанном спискС. Π₯эш-Ρ‚Π°Π±Π»ΠΈΡ†Π° являСтся простым массивом, хранящим элСмСнты KeyValue:

struct KeyValue
{
    uint32_t key;
    uint32_t value;
};

Π Π°Π·ΠΌΠ΅Ρ€ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Ρ€Π°Π²Π΅Π½ Π΄Π²ΠΎΠΉΠΊΠ΅ Π² стСпСни, Π° Π½Π΅ простому числу, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ для примСнСния pow2/AND-маски достаточно ΠΎΠ΄Π½ΠΎΠΉ быстрой инструкции, Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ модуля Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅. Π­Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ Π² случаС Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ³ΠΎ зондирования, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΡ€ΠΈ Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΌ поискС ΠΏΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ индСкс слота Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Ρ‘Ρ€Π½ΡƒΡ‚ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ слот. И Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ добавляСтся ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ слотС.

Π’Π°Π±Π»ΠΈΡ†Π° Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ»ΡŽΡ‡ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта, Π° Π½Π΅ Ρ…ΡΡˆ ΠΊΠ»ΡŽΡ‡Π°. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°Π±Π»ΠΈΡ†Π° Ρ…Ρ€Π°Π½ΠΈΡ‚ лишь 32-Π±ΠΈΡ‚Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ, Ρ…ΡΡˆ вычисляСтся ΠΎΡ‡Π΅Π½ΡŒ быстро. Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ…ΡΡˆ Murmur3, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСт лишь нСсколько сдвигов, XOR-ΠΎΠ² ΠΈ ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠΉ.

Π’ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ примСняСтся ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ° Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ, которая Π½Π΅ зависит ΠΎΡ‚ порядка размСщСния Π² памяти. Π”Π°ΠΆΠ΅ Ссли Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ записи Π½Π°Ρ€ΡƒΡˆΠ°ΡŽΡ‚ ΠΎΡ‡Π΅Ρ€Ρ‘Π΄Π½ΠΎΡΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ‚Π°ΠΊΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° всё Ρ€Π°Π²Π½ΠΎ сохранит ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ состояниС. Об этом ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π½ΠΈΠΆΠ΅. ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ° ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π°ΠΌΠΈ, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ тысячи ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

ΠšΠ»ΡŽΡ‡ΠΈ ΠΈ значСния Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ пустыми.

Код ΠΌΠΎΠΆΠ½ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ ΠΌΠΎΠ³ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈ 64-Π±ΠΈΡ‚Π½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ ΠΈ значСния. Для ΠΊΠ»ΡŽΡ‡Π΅ΠΉ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния, записи ΠΈ сравнСния с ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌ (compare-and-swap). А для Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π½ΡƒΠΆΠ½Ρ‹ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния ΠΈ записи. К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, Π² CUDA ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния-записи для 32- ΠΈ 64-Π±ΠΈΡ‚Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹ΠΌΠΈ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΈ Π²Ρ‹Ρ€ΠΎΠ²Π½Π΅Π½Ρ‹ СстСствСнным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ (см. здСсь), Π° соврСмСнныС Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ 64-Π±ΠΈΡ‚Π½Ρ‹Π΅ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ сравнСния с ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌ. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π΅ Π½Π° 64 Π±ΠΈΡ‚Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ нСсколько снизится.

БостояниС Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

КаТдая ΠΏΠ°Ρ€Π° ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… состояний:

  • ΠšΠ»ΡŽΡ‡ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ пусты. Π’ Ρ‚Π°ΠΊΠΎΠΌ состоянии Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° инициализируСтся.
  • ΠšΠ»ΡŽΡ‡ Π±Ρ‹Π» записан, Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΅Ρ‰Ρ‘ Π½Π΅Ρ‚. Если Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ исполнСния Π² этот ΠΌΠΎΠΌΠ΅Π½Ρ‚ считываСт Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚ΠΎ Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ пустоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π­Ρ‚ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ρ‚ΠΎ ΠΆΠ΅ самоС ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ Π±Ρ‹, Ссли Π±Ρ‹ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ исполнСния ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π» Ρ‡ΡƒΡ‚ΡŒ Ρ€Π°Π½ΡŒΡˆΠ΅, Π° ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎΠΉ структурС Π΄Π°Π½Π½Ρ‹Ρ….
  • Записаны ΠΈ ΠΊΠ»ΡŽΡ‡, ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
  • Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ доступно для Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² исполнСния, Π° ΠΊΠ»ΡŽΡ‡ β€” Π΅Ρ‰Ρ‘ Π½Π΅Ρ‚. Π’Π°ΠΊΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ модСль программирования Π² CUDA ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ слабо ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡Π΅Π½Π½ΡƒΡŽ модСль памяти. Π­Ρ‚ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈ любом событии ΠΊΠ»ΡŽΡ‡ всё Π΅Ρ‰Ρ‘ пустой, Π΄Π°ΠΆΠ΅ Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΈΠΌ ΡƒΠΆΠ΅ Π½Π΅ являСтся.

Π’Π°ΠΆΠ½Ρ‹ΠΉ нюанс Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ»ΡŽΡ‡ Π±Ρ‹Π» записан Π² слот, ΠΎΡ‚ ΡƒΠΆΠ΅ Π½Π΅ пСрСмСщаСтся β€” Π΄Π°ΠΆΠ΅ Ссли ΠΊΠ»ΡŽΡ‡ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»Ρ‘Π½, ΠΎΠ± этом ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π½ΠΈΠΆΠ΅.

Код Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π΄Π°ΠΆΠ΅ со слабо упорядочСнными модСлями памяти, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ извСстСн порядок чтСния ΠΈ записСй Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ. Когда ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ΡŒ вставку, поиск ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅, ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ каТдая ΠΏΠ°Ρ€Π° ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ находится Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… Π²Ρ‹ΡˆΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½Ρ‹Ρ… состояний.

Вставка Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ

CUDA-функция, которая вставляСт Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΏΠ°Ρ€Ρ‹ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, выглядит Ρ‚Π°ΠΊ:

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);
    }
}

Для вставки ΠΊΠ»ΡŽΡ‡Π° ΠΊΠΎΠ΄ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎ массиву Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ начиная с Ρ…ΡΡˆΠ° вставляСмого ΠΊΠ»ΡŽΡ‡Π°. Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ слотС массива выполняСтся атомарная опСрация сравнСния с ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌ, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ»ΡŽΡ‡ Π² этом слотС сравниваСтся с пустым. Если обнаруТиваСтся нСсоотвСтствиС, Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Π² слотС обновляСтся Π½Π° вставляСмый ΠΊΠ»ΡŽΡ‡, Π° Π·Π°Ρ‚Π΅ΠΌ возвращаСтся ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ слота. Если этот ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ Π±Ρ‹Π» пустым ΠΈΠ»ΠΈ соотвСтствовал вставляСмому ΠΊΠ»ΡŽΡ‡Ρƒ, Π·Π½Π°Ρ‡ΠΈΡ‚ ΠΊΠΎΠ΄ Π½Π°ΡˆΡ‘Π» подходящий для вставки слот ΠΈ вносит Π² слот вставляСмоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

Если Π² ΠΎΠ΄Π½ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ ядра gpu_hashtable_insert() Π΅ΡΡ‚ΡŒ нСсколько элСмСнтов с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ, Ρ‚ΠΎΠ³Π΄Π° любоС ΠΈΠ· ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ записано Π² слот ΠΊΠ»ΡŽΡ‡Π°. Π­Ρ‚ΠΎ считаСтся Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ: ΠΎΠ΄Π½Π° ΠΈΠ· ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ записи ΠΊΠ»ΡŽΡ‡Π°-значСния Π² Ρ…ΠΎΠ΄Π΅ Π²Ρ‹Π·ΠΎΠ²Π° Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ, Π½ΠΎ ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ всё это происходит ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² исполнСния, Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, какая опСрация записи Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ Π±ΡƒΠ΄Π΅Ρ‚ послСднСй.

Поиск Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅

Код для поиска ΠΊΠ»ΡŽΡ‡Π΅ΠΉ:

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);
        }
}

Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π°, хранящСгося Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅, ΠΌΡ‹ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠΎ массиву начиная с Ρ…ΡΡˆΠ° искомого ΠΊΠ»ΡŽΡ‡Π°. Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ слотС ΠΌΡ‹ провСряСм, являСтся Π»ΠΈ ΠΊΠ»ΡŽΡ‡ Ρ‚Π΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ, ΠΈ Ссли Π΄Π°, Ρ‚ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’Π°ΠΊΠΆΠ΅ ΠΌΡ‹ провСряСм, являСтся Π»ΠΈ ΠΊΠ»ΡŽΡ‡ пустым, ΠΈ Ссли Π΄Π°, Ρ‚ΠΎ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅ΠΌ поиск.

Если Π½Π°ΠΌ Π½Π΅ удаётся Π½Π°ΠΉΡ‚ΠΈ ΠΊΠ»ΡŽΡ‡, Ρ‚ΠΎ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ пустоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

ВсС эти ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ поиска ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ Π² Ρ…ΠΎΠ΄Π΅ вставок ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ. КаТдая ΠΏΠ°Ρ€Π° Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ для ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΠ΄Π½ΠΎ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… Π²Ρ‹ΡˆΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½Ρ‹Ρ… состояний.

Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅

Код для удалСния ΠΊΠ»ΡŽΡ‡Π΅ΠΉ:

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(), Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠΈ совпадСния ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ ΠΎΠ½ Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ пустым.

Как ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ Π²Ρ‹ΡˆΠ΅, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ»ΡŽΡ‡ записан Π² слот, ΠΎΠ½ ΡƒΠΆΠ΅ Π½Π΅ пСрСмСщаСтся. Π”Π°ΠΆΠ΅ ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ элСмСнта ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΊΠ»ΡŽΡ‡ остаётся Π½Π° мСстС, просто Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ становится пустым. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ записи значСния слота, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅ Π²Π°ΠΆΠ½ΠΎ, являСтся Π»ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ пустым ΠΈΠ»ΠΈ Π½Π΅Ρ‚ β€” ΠΎΠ½ΠΎ всё-Ρ€Π°Π²Π½ΠΎ станСт пустым.

ИзмСнСниС Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ создания Π±ΠΎΠ»Π΅Π΅ ΠΊΡ€ΡƒΠΏΠ½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈ вставки Π² Π½Π΅Ρ‘ нСпустых элСмСнтов ΠΈΠ· старой Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π― эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π», ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ…ΠΎΡ‚Π΅Π» ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π·Π΅Ρ† ΠΊΠΎΠ΄Π° простым. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π² CUDA-ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти часто выполняСтся Π² хост-ΠΊΠΎΠ΄Π΅, Π° Π½Π΅ Π² ядрС CUDA.

Π’ ΡΡ‚Π°Ρ‚ΡŒΠ΅ A Lock-Free Wait-Free Hash Table описано, ΠΊΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ структуру Π΄Π°Π½Π½Ρ‹Ρ…, Π·Π°Ρ‰ΠΈΡ‰Ρ‘Π½Π½ΡƒΡŽ ΠΎΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ.

ΠšΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ

Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½Ρ‹Ρ… Π²Ρ‹ΡˆΠ΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ… ΠΊΠΎΠ΄Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ 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);
    }
}

Π₯эш-Ρ‚Π°Π±Π»ΠΈΡ†Π° с Π·Π°Ρ‰ΠΈΡ‚ΠΎΠΉ ΠΎΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½Ρ‹Π΅ вставки, поиски ΠΈ удалСния. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠ°Ρ€Ρ‹ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ всСгда находятся Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… состояний, Π° ΠΊΠ»ΡŽΡ‡ΠΈ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ, Ρ‚Π°Π±Π»ΠΈΡ†Π° Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΌ использовании ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Ρ€Π°Π·Π½Ρ‹Ρ… Π²ΠΈΠ΄ΠΎΠ².

Однако Ссли ΠΌΡ‹ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈΠ· вставок ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ, ΠΈ Ссли Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ массивС ΠΏΠ°Ρ€ содСрТатся Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ΡΡ ΠΊΠ»ΡŽΡ‡ΠΈ, Ρ‚ΠΎ ΠΌΡ‹ Π½Π΅ смоТСм ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠ°Ρ€Ρ‹ «побСдят» β€” Π±ΡƒΠ΄ΡƒΡ‚ записаны Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ послСдними. Допустим, ΠΌΡ‹ Π²Ρ‹Π·Π²Π°Π»ΠΈ ΠΊΠΎΠ΄ вставки со Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ массивом ΠΈΠ· ΠΏΠ°Ρ€ 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() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ простой (plain) ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ (volatile) ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° массив ΠΏΠ°Ρ€ Π² Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅. ДокумСнтация CUDA ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ:

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎ своСму ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Π½ΠΈΡŽ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния ΠΈ записи Π² Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ»ΠΈ ΠΎΠ±Ρ‰ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ … Π­Ρ‚ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова volatile: … любая ссылка Π½Π° эту ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ компилируСтся Π² Π½Π°ΡΡ‚ΠΎΡΡ‰ΡƒΡŽ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ чтСния ΠΈΠ»ΠΈ записи Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ.

БообраТСния коррСктности Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ примСнСния volatile. Если ΠΏΠΎΡ‚ΠΎΠΊ исполнСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π·Π°ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния, Ρ‚ΠΎ это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ. Но всё ΠΆΠ΅ это информация ΠΈΠ· ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ состояния Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° ядра. Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ°ΠΌΡƒΡŽ ΡΠ²Π΅ΠΆΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ, Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ volatile, Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π° Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ снизится ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ: ΠΏΠΎ ΠΌΠΎΠΈΠΌ тСстам β€” ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ 32 ΠΌΠ»Π½ элСмСнтов ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ снизилась с 500 ΠΌΠ»Π½ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ/сСк Π΄ΠΎ 450 ΠΌΠ»Π½ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ/сСк.

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

Π’ тСстС Π½Π° вставку 64 ΠΌΠ»Π½ элСмСнтов ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ 32 ΠΌΠ»Π½ ΠΈΠ· Π½ΠΈΡ… конкурСнция ΠΌΠ΅ΠΆΠ΄Ρƒ std::unordered_map ΠΈ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ для GPU фактичСски отсутствуСт:

ΠŸΡ€ΠΎΡΡ‚Π°Ρ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° для GPU
std::unordered_map ΠΏΠΎΡ‚Ρ€Π°Ρ‚ΠΈΠ»Π° 70 691 мс Π½Π° вставку ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ элСмСнтов с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ освобоТдСниСм unordered_map (освобоТдСниС ΠΎΡ‚ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ΠΎΠ² элСмСнтов Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π΅ΠΌΠ°Π»ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ unordered_map Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ многочислСнныС выдСлСния памяти). ЧСстно говоря, Ρƒ std:unordered_map совсСм Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ограничСния. Π­Ρ‚ΠΎ Π΅Π΄ΠΈΠ½Ρ‹ΠΉ CPU-ΠΏΠΎΡ‚ΠΎΠΊ исполнСния, ΠΎΠ½ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠ»ΡŽΡ‡ΠΈ-значСния любого Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€ΠΈ высоких коэффициСнтах использования ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ послС многочислСнных ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ.

Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ для GPU ΠΈ ΠΌΠ΅ΠΆΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ взаимодСйствия составила 984 мс. Бюда Π²Ρ…ΠΎΠ΄ΠΈΡ‚ врСмя, Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½Π½ΠΎΠ΅ Π½Π° Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π² памяти ΠΈ Π΅Ρ‘ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ (ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠ΅ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ 1 Π“Π± памяти, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π² CUDA Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ врСмя), вставка ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ элСмСнтов, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ Π½ΠΈΠΌ. Π’Π°ΠΊΠΆΠ΅ ΡƒΡ‡Ρ‚Π΅Π½Ρ‹ всС копирования Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΈ ΠΈΠ· памяти Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹.

Π Π°Π±ΠΎΡ‚Π° самой Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ заняла 271 мс. Бюда Π²Ρ…ΠΎΠ΄ΠΈΡ‚ врСмя, ΠΏΠΎΡ‚Ρ€Π°Ρ‡Π΅Π½Π½ΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚ΠΎΠΉ Π½Π° вставку ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ элСмСнтов, ΠΈ Π½Π΅ учитываСтся врСмя Π½Π° ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΈ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠ΅ΠΉΡΡ Ρ‚Π°Π±Π»ΠΈΡ†Π΅. Если GPU-Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΆΠΈΠ²Ρ‘Ρ‚ Π΄ΠΎΠ»Π³ΠΎ, ΠΈΠ»ΠΈ Ссли Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° содСрТится Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ Π² памяти Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для создания Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π΄Ρ€ΡƒΠ³ΠΈΠΌ GPU-ΠΊΠΎΠ΄ΠΎΠΌ, Π° Π½Π΅ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΌ процСссором), Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ тСстирования Ρ€Π΅Π»Π΅Π²Π°Π½Ρ‚Π΅Π½.

Π₯эш-Ρ‚Π°Π±Π»ΠΈΡ†Π° для Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹ дСмонстрируСт Π²Ρ‹ΡΠΎΠΊΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ благодаря большой пропускной способности ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌΡƒ Ρ€Π°ΡΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ²Π°Π½ΠΈΡŽ.

НСдостатки

Π£ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π΅ΡΡ‚ΡŒ нСсколько ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ:

  • Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΌΡƒ Π·ΠΎΠ½Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ кластСризация, ΠΈΠ·-Π·Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ»ΡŽΡ‡ΠΈ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ идСально.
  • ΠšΠ»ΡŽΡ‡ΠΈ Π½Π΅ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ delete ΠΈ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ Π·Π°Π³Ρ€ΠΎΠΌΠΎΠΆΠ΄Π°ΡŽΡ‚ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ.

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚ постСпСнно ΡΠ½ΠΈΠΆΠ°Ρ‚ΡŒΡΡ, особСнно Ссли ΠΎΠ½Π° сущСствуСт Π΄ΠΎΠ»Π³ΠΎ ΠΈ Π² Π½Π΅ΠΉ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ многочислСнныС вставки ΠΈ удалСния. Одним ΠΈΠ· способов смягчСния этих нСдостатков являСтся ΠΏΠ΅Ρ€Π΅Ρ…ΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ с достаточно Π½ΠΈΠ·ΠΊΠΈΠΌ коэффициСнтом использования ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠ΅ΠΉ ΡƒΠ΄Π°Π»Ρ‘Π½Π½Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ описанныС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ Π²Ρ‹ΡˆΠ΅ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ для создания Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π½Π° 128 ΠΌΠ»Π½ элСмСнтов, цикличСски Π±ΡƒΠ΄Ρƒ Π²ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ 4 ΠΌΠ»Π½ элСмСнтов, ΠΏΠΎΠΊΠ° Π½Π΅ заполню 124 ΠΌΠ»Π½ слотов (коэффициСнт использования ΠΎΠΊΠΎΠ»ΠΎ 0,96). Π’ΠΎΡ‚ Ρ‚Π°Π±Π»ΠΈΡ†Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ², каТдая строка β€” это Π²Ρ‹Π·ΠΎΠ² ядра CUDA со вставкой 4 ΠΌΠ»Π½ Π½ΠΎΠ²Ρ‹Ρ… элСмСнтов Π² ΠΎΠ΄Π½Ρƒ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ:

ΠšΠΎΡΡ„Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚ использования
Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ вставки 4 194 304 элСмСнтов

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 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ/сСк.)

По ΠΌΠ΅Ρ€Π΅ роста коэффициСнта использования ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сниТаСтся. Π­Ρ‚ΠΎ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв. Если ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ вставляСт Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ элСмСнты, Π° Π·Π°Ρ‚Π΅ΠΌ отбрасываСт ΠΈΡ… (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ подсчётС слов Π² ΠΊΠ½ΠΈΠ³Π΅), Ρ‚ΠΎ это Π½Π΅ являСтся ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ. Но Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡƒΡŽΡ‰ΡƒΡŽ Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² графичСском Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π΅ для хранСния нСпустых частСй ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ часто вставляСт ΠΈ удаляСт ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ), Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ нСприятности.

И ΠΈΠ·ΠΌΠ΅Ρ€ΠΈΠ» Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ зондирования Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ послС 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 Π“Π±), всё ΠΆΠ΅ Ρ‚Π΅Ρ€ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΎΠ±ΡŠΡ‘ΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅ самым ΠΌΡƒΠ΄Ρ€Ρ‹ΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ.

ПозднСС я ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π½Π°ΠΏΠΈΡˆΡƒ ΠΎ создании Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ† для Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с Π³Π»ΡƒΠ±ΠΈΠ½ΠΎΠΉ зондирования, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΎ способах ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ использования ΡƒΠ΄Π°Π»Ρ‘Π½Π½Ρ‹Ρ… слотов.

Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ Π³Π»ΡƒΠ±ΠΈΠ½Ρ‹ зондирования

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ зондирования ΠΊΠ»ΡŽΡ‡Π°, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ Ρ…ΡΡˆ ΠΊΠ»ΡŽΡ‡Π° (Π΅Π³ΠΎ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ индСкс Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅) ΠΈΠ· Π΅Π³ΠΎ фактичСского Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ индСкса:

// 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.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Если Ρƒ вас Π΅ΡΡ‚ΡŒ вопросы ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, Π½Π°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΌΠ½Π΅ Π² Twitter ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.

Π­Ρ‚ΠΎ ΠΊΠΎΠ΄ написан ΠΏΠΎΠ΄ Π²Π΄ΠΎΡ…Π½ΠΎΠ²Π΅Π½ΠΈΠ΅ΠΌ ΠΎΡ‚ прСкрасных статСй:

Π’ Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ я ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΡƒ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎ рСализациях Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ† для Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚ ΠΈ Π±ΡƒΠ΄Ρƒ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. Π’ ΠΏΠ»Π°Π½Π°Ρ… Ρƒ мСня связываниС Π² Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ, Ρ…ΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π ΠΎΠ±ΠΈΠ½Π° Π“ΡƒΠ΄Π° ΠΈ ΠΊΡƒΠΊΡƒΡˆΠΊΠΈΠ½ΠΎ Ρ…ΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ с использованиСм Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π² структурах Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ для Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com