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

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

Π’ΠΎΠ²Π° Π΅ проста Ρ…ΡΡˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π·Π° 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-Π±ΠΈΡ‚ΠΎΠ²ΠΈ ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π΅, Ρ…ΡΡˆΡŠΡ‚ сС изчислява ΠΌΠ½ΠΎΠ³ΠΎ Π±ΡŠΡ€Π·ΠΎ. Π’ прСдоставСния ΠΊΠΎΠ΄ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ…ΡΡˆ 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 ms (361,314798 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,03
11,751424 ms (356,918799 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,06
11,942592 ms (351,205515 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,09
12,081120 ms (347,178429 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,12
12,242560 ms (342,600233 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,16
12,396448 ms (338,347235 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,19
12,533024 ms (334,660176 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,22
12,703328 ms (330,173626 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,25
12,884512 ms (325,530693 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,28
13,033472 ms (321,810182 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,31
13,239296 ms (316,807174 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,34
13,392448 ms (313,184256 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,37
13,624000 ms (307,861434 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,41
13,875520 ms (302,280855 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,44
14,126528 ms (296,909756 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,47
14,399328 ms (291,284699 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,50
14,690304 ms (285,515123 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,53
15,039136 ms (278,892623 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,56
15,478656 ms (270,973402 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,59
15,985664 ms (262,379092 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,62
16,668673 ms (251,627968 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,66
17,587200 ms (238,486174 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,69
18,690048 ms (224,413765 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,72
20,278816 ms (206,831789 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,75
22,545408 ms (186,038058 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,78
26,053312 ms (160,989275 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,81
31,895008 ms (131,503463 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,84
42,103294 ms (99,619378 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,87
61,849056 ms (67,815164 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,90
105,695999 ms (39,682713 ΠΌΠ»Π½ ΠΊΠ»ΡŽΡ‡Π°/сСк.)

0,94
240,204636 ms (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