ΠŸΡ€ΠΎΡΡ‚Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π·Π° GPU

ΠŸΡ€ΠΎΡΡ‚Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π·Π° GPU
ΠšΠ°Ρ‡ΠΈΡ… Π½Π° Github Π½ΠΎΠ² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ A Simple GPU Hash Table.

Π’ΠΎΠ²Π° Π΅ проста Ρ…Π΅Ρˆ Ρ‚Π°Π±Π»ΠΈΡ†Π° Π·Π° GPU, способна Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° стотици ΠΌΠΈΠ»ΠΈΠΎΠ½ΠΈ вмъквания Π·Π° сСкунда. На моя Π»Π°ΠΏΡ‚ΠΎΠΏ с NVIDIA GTX 1060 ΠΊΠΎΠ΄ΡŠΡ‚ вмъква 64 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° случайно Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ΠΈ Π΄Π²ΠΎΠΉΠΊΠΈ ΠΊΠ»ΡŽΡ‡-стойност Π·Π° ΠΎΠΊΠΎΠ»ΠΎ 210 ms ΠΈ ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π° 32 ΠΌΠΈΠ»ΠΈΠΎΠ½Π° Π΄Π²ΠΎΠΉΠΊΠΈ Π·Π° ΠΎΠΊΠΎΠ»ΠΎ 64 ms.

ВоСст скоростта Π½Π° Π»Π°ΠΏΡ‚ΠΎΠΏΠ° Π΅ ΠΎΠΊΠΎΠ»ΠΎ 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);
    }
}

Π₯Сш-Ρ‚Π°Π±Π»ΠΈΡ†Π° с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΈ вмъквания, Ρ‚ΡŠΡ€ΡΠ΅Π½ΠΈΡ ΠΈ изтривания. Въй ΠΊΠ°Ρ‚ΠΎ Π΄Π²ΠΎΠΉΠΊΠΈΡ‚Π΅ ΠΊΠ»ΡŽΡ‡-стойност Π²ΠΈΠ½Π°Π³ΠΈ са Π² Π΅Π΄Π½ΠΎ ΠΎΡ‚ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈΡ‚Π΅ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΡ ΠΈ ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π΅Ρ‚Π΅ Π½Π΅ сС прСмСстват, Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π° корСктност Π΄ΠΎΡ€ΠΈ ΠΏΡ€ΠΈ simultaneus ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΎΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ Π²ΠΈΠ΄.

Ако ΠΎΠ±Π°Ρ‡Π΅ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΎΡ‚ вмъквания ΠΈ изтривания, ΠΈ Π°ΠΊΠΎ входният масив ΠΎΡ‚ Π΄Π²ΠΎΠΉΠΊΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π΄ΡƒΠ±Π»ΠΈΡ€Π°Ρ‰ΠΈ сС ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π΅, няма Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠΎΠΈ Π΄Π²ΠΎΠΉΠΊΠΈ "ΠΏΠΎΠ±Π΅ΠΆΠ΄Π°Π²Π°Ρ‚" β€” ΠΊΠΎΠΈ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ записани Π² Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° послСдни. Π”Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ смС ΠΈΠ·Π²ΠΈΠΊΠ°Π»ΠΈ ΠΊΠΎΠ΄Π° Π·Π° вмъкванС с Π²Ρ…ΠΎΠ΄Π΅Π½ масив ΠΎΡ‚ Π΄Π²ΠΎΠΉΠΊΠΈ 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 ΠΊΠΎΠ΄, Π° Π½Π΅ ΠΎΡ‚ цСнтралния процСсор), Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ тСста Π΅ Π°ΠΊΡ‚ΡƒΠ°Π»Π΅Π½.

Π₯Сш-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Π·Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π° дСмонстрира висока производитСлност Π±Π»Π°Π³ΠΎΠ΄Π°Ρ€Π΅Π½ΠΈΠ΅ Π½Π° голямата пропускна способност ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡ‚ΠΎ ΠΏΠ°Ρ€Π°Π»Π΅Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅.

ΠΠ΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ†ΠΈ

АрхитСктурата Π½Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° ΠΈΠΌΠ° няколко ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° сС ΠΈΠΌΠ°Ρ‚ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄:

  • Π›ΠΈΠ½Π΅ΠΉΠ½ΠΎΡ‚ΠΎ Π·ΠΎΠ½ΠΈΡ€Π°Π½Π΅ Π΅ прСпятствано ΠΎΡ‚ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ΠΈΠ·Π°Ρ†ΠΈΡ, ΠΏΠΎΡ€Π°Π΄ΠΈ която ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π΅Ρ‚Π΅ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° Π½Π΅ са Ρ€Π°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈ ΠΈΠ΄Π΅Π°Π»Π½ΠΎ.
  • ΠšΠ»ΡŽΡ‡ΠΎΠ²Π΅Ρ‚Π΅ Π½Π΅ сС ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ с функция ΠΈΠ·Ρ‚Ρ€ΠΈΠΉ ΠΈ с Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π°Ρ‚Ρ€ΡƒΠΏΠ²Π°Ρ‚ Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°.

Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ²Π° производитСлността Π½Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅ постСпСнно Π΄Π° намалява, особСно Π°ΠΊΠΎ тя ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π° дълго ΠΈ Π΅ Π² нСя ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π½ΠΈ мноТСство вмъквания ΠΈ изтривания. Π•Π΄ΠΈΠ½ ΠΎΡ‚ Π½Π°Ρ‡ΠΈΠ½ΠΈΡ‚Π΅ Π·Π° смСкчаванС Π½Π° Ρ‚Π΅Π·ΠΈ Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ†ΠΈ Π΅ ΠΏΡ€Π΅Ρ…Π΅ΡˆΠΈΡ€Π°Π½Π΅ Π² Π½ΠΎΠ²Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° с Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ нисък ΠΊΠΎΠ΅Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚ Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΈΠ·Ρ‚Ρ€ΠΈΡ‚ΠΈΡ‚Π΅ ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π΅ ΠΏΡ€ΠΈ ΠΏΡ€Π΅Ρ…Π΅ΡˆΠΈΡ€Π°Π½Π΅.

Π—Π° Π΄Π° ΠΈΠ»ΡŽΡΡ‚Ρ€ΠΈΡ€Π°ΠΌ описанитС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ горСпосочСния ΠΊΠΎΠ΄ Π·Π° създаванС Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° с 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

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster