ΠŸΡ€ΠΎΡΡ‚Π° Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π° Π·Π° 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);
    }
}

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

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

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

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