TÄ ir vienkÄrÅ”a GPU hash tabula, kas spÄj apstrÄdÄt simtiem miljonu ieliktÅu sekundÄ. ManÄ NVIDIA GTX 1060 klÄpjdatorÄ kods ievieto 64 miljonus nejauÅ”i Ä£enerÄtu atslÄgu vÄrtÄ«bu pÄru aptuveni 210 ms laikÄ un noÅem 32 miljonus pÄru aptuveni 64 ms laikÄ.
Tas nozÄ«mÄ, ka klÄpjdatora Ätrums ir aptuveni 300 miljoni ievietoÅ”anas/sek un 500 miljoni dzÄÅ”anas/sek.
Tabula ir uzrakstÄ«ta CUDA, lai gan to paÅ”u tehniku āāvar izmantot HLSL vai GLSL. IevieÅ”anai ir vairÄki ierobežojumi, lai nodroÅ”inÄtu augstu veiktspÄju videokartÄ:
Tiek apstrÄdÄtas tikai 32 bitu atslÄgas un tÄs paÅ”as vÄrtÄ«bas.
Hash tabulai ir fiksÄts izmÄrs.
Un Å”im izmÄram jÄbÅ«t vienÄdam ar diviem lÄ«dz jaudai.
AtslÄgÄm un vÄrtÄ«bÄm ir jÄrezervÄ vienkÄrÅ”s norobežotÄja marÄ·ieris (iepriekÅ” minÄtajÄ kodÄ tas ir 0xffffffff).
Hash galds bez slÄdzenÄm
JaucÄjtabulÄ tiek izmantota atvÄrtÄ adrese ar lineÄrÄ zondÄÅ”ana, tas ir, tas ir vienkÄrÅ”i atslÄgu un vÄrtÄ«bu pÄru masÄ«vs, kas tiek glabÄts atmiÅÄ un kam ir izcila keÅ”atmiÅas veiktspÄja. To paÅ”u nevar teikt par Ä·Ädes pievienoÅ”anu, kas ietver rÄdÄ«tÄja meklÄÅ”anu saistÄ«tajÄ sarakstÄ. Hash tabula ir vienkÄrÅ”s masÄ«vs, kurÄ tiek glabÄti elementi KeyValue:
Tabulas izmÄrs ir pakÄpÄ divi, nevis pirmskaitlis, jo pietiek ar vienu Ätru instrukciju, lai uzliktu masku pow2/AND, bet moduļa operators ir daudz lÄnÄks. Tas ir svarÄ«gi lineÄrÄs zondÄÅ”anas gadÄ«jumÄ, jo lineÄrÄs tabulas uzmeklÄÅ”anÄ slota indekss ir jÄiekļauj katrÄ slotÄ. Un rezultÄtÄ operÄcijas izmaksas tiek pievienotas modulo katrÄ slotÄ.
TabulÄ tiek saglabÄta tikai katra elementa atslÄga un vÄrtÄ«ba, nevis atslÄgas jaucÄjkods. TÄ kÄ tabulÄ tiek saglabÄtas tikai 32 bitu atslÄgas, hash tiek aprÄÄ·inÄts ļoti Ätri. IepriekÅ” minÄtais kods izmanto Murmur3 hash, kas veic tikai dažas maiÅas, XOR un reizinÄÅ”anu.
JaucÄj tabulÄ tiek izmantotas bloÄ·ÄÅ”anas aizsardzÄ«bas metodes, kas nav atkarÄ«gas no atmiÅas secÄ«bas. Pat ja dažas rakstÄ«Å”anas darbÄ«bas izjauc citu Å”Ädu darbÄ«bu secÄ«bu, hash tabula joprojÄm saglabÄs pareizo stÄvokli. Par to mÄs runÄsim tÄlÄk. Å Ä« tehnika lieliski darbojas ar videokartÄm, kurÄs vienlaikus darbojas tÅ«kstoÅ”iem pavedienu.
AtslÄgas un vÄrtÄ«bas hash tabulÄ tiek inicializÄtas, lai tÄs bÅ«tu tukÅ”as.
Kodu var modificÄt, lai apstrÄdÄtu arÄ« 64 bitu atslÄgas un vÄrtÄ«bas. AtslÄgÄm ir nepiecieÅ”amas atomu lasÄ«Å”anas, rakstÄ«Å”anas un salÄ«dzinÄÅ”anas un apmaiÅas darbÄ«bas. Un vÄrtÄ«bÄm ir nepiecieÅ”amas atomu lasÄ«Å”anas un rakstÄ«Å”anas darbÄ«bas. Par laimi, CUDA lasÄ«Å”anas un rakstÄ«Å”anas darbÄ«bas 32 un 64 bitu vÄrtÄ«bÄm ir atomÄras, ja vien tÄs ir dabiski izlÄ«dzinÄtas (skatiet tÄlÄk). Å”eit), un modernÄs videokartes atbalsta 64 bitu atomu salÄ«dzinÄÅ”anas un apmaiÅas darbÄ«bas. Protams, pÄrejot uz 64 bitiem, veiktspÄja nedaudz samazinÄsies.
JaukÅ”anas tabulas stÄvoklis
Katram atslÄgu un vÄrtÄ«bu pÄrim jaukÅ”anas tabulÄ var bÅ«t viens no Äetriem stÄvokļiem:
AtslÄga un vÄrtÄ«ba ir tukÅ”a. Å ajÄ stÄvoklÄ« hash tabula tiek inicializÄta.
AtslÄga ir pierakstÄ«ta, bet vÄrtÄ«ba vÄl nav uzrakstÄ«ta. Ja cits pavediens paÅ”laik lasa datus, tas atgriežas tukÅ”s. Tas ir normÄli, tas pats bÅ«tu noticis, ja cits izpildes pavediens bÅ«tu darbojies nedaudz agrÄk, un mÄs runÄjam par vienlaicÄ«gu datu struktÅ«ru.
Tiek ierakstÄ«ta gan atslÄga, gan vÄrtÄ«ba.
VÄrtÄ«ba ir pieejama citiem izpildes pavedieniem, bet atslÄga vÄl nav pieejama. Tas var notikt tÄpÄc, ka CUDA programmÄÅ”anas modelim ir brÄ«vi sakÄrtots atmiÅas modelis. Tas ir normÄli; jebkurÄ gadÄ«jumÄ atslÄga joprojÄm ir tukÅ”a, pat ja vÄrtÄ«ba vairs nav tÄda.
SvarÄ«ga nianse ir tÄ, ka, tiklÄ«dz atslÄga ir ierakstÄ«ta slotÄ, tÄ vairs nekustas ā pat ja atslÄga tiek izdzÄsta, par to mÄs runÄsim tÄlÄk.
Hash tabulas kods darbojas pat ar brÄ«vi sakÄrtotiem atmiÅas modeļiem, kuros atmiÅas lasÄ«Å”anas un rakstÄ«Å”anas secÄ«ba nav zinÄma. AplÅ«kojot ievietoÅ”anu, uzmeklÄÅ”anu un dzÄÅ”anu hash tabulÄ, atcerieties, ka katrs atslÄgas un vÄrtÄ«bas pÄris atrodas vienÄ no Äetriem iepriekÅ” aprakstÄ«tajiem stÄvokļiem.
IevietoÅ”ana hash tabulÄ
CUDA funkcija, kas ievieto atslÄgu-vÄrtÄ«bu pÄrus hash tabulÄ, izskatÄs Å”Ädi:
Lai ievietotu atslÄgu, kods atkÄrtojas caur hash tabulas masÄ«vu, sÄkot ar ievietotÄs atslÄgas jaucÄjkodu. Katrs masÄ«va slots veic atomu salÄ«dzinÄÅ”anas un maiÅas darbÄ«bu, kas salÄ«dzina Å”ajÄ slotÄ esoÅ”o atslÄgu ar tukÅ”o. Ja tiek konstatÄta neatbilstÄ«ba, slotÄ esoÅ”Ä atslÄga tiek atjauninÄta ar ievietoto atslÄgu, un pÄc tam tiek atgriezta sÄkotnÄjÄ slota atslÄga. Ja Ŕī sÄkotnÄjÄ atslÄga bija tukÅ”a vai atbilda ievietotajai atslÄgai, kods atrada ievietoÅ”anai piemÄrotu slotu un ievietoja ievietoto vÄrtÄ«bu slotÄ.
Ja vienÄ kodola izsaukumÄ gpu_hashtable_insert() ir vairÄki elementi ar vienu un to paÅ”u atslÄgu, tad jebkuru no to vÄrtÄ«bÄm var ierakstÄ«t atslÄgas slotÄ. Tas tiek uzskatÄ«ts par normÄlu: viena no atslÄgas vÄrtÄ«bas ierakstiem zvana laikÄ izdosies, taÄu, tÄ kÄ tas viss notiek paralÄli vairÄkos izpildes pavedienos, mÄs nevaram paredzÄt, kura atmiÅas ierakstÄ«Å”ana bÅ«s pÄdÄjÄ.
Lai atrastu tabulÄ saglabÄtÄs atslÄgas vÄrtÄ«bu, mÄs atkÄrtojam masÄ«vu, sÄkot ar meklÄtÄs atslÄgas jaucÄjkodu. KatrÄ slotÄ mÄs pÄrbaudÄm, vai atslÄga ir tÄ, ko meklÄjam, un, ja tÄ, mÄs atgriežam tÄs vÄrtÄ«bu. MÄs arÄ« pÄrbaudÄm, vai atslÄga ir tukÅ”a, un, ja tÄ, mÄs pÄrtraucam meklÄÅ”anu.
Ja nevaram atrast atslÄgu, kods atgriež tukÅ”u vÄrtÄ«bu.
Visas Ŕīs meklÄÅ”anas darbÄ«bas var veikt vienlaikus, ievietojot un dzÄÅ”ot. Katram tabulas pÄrim bÅ«s viens no Äetriem iepriekÅ” aprakstÄ«tajiem plÅ«smas stÄvokļiem.
AtslÄgas dzÄÅ”ana tiek veikta neparastÄ veidÄ: mÄs atstÄjam atslÄgu tabulÄ un atzÄ«mÄjam tÄs vÄrtÄ«bu (nevis paÅ”u atslÄgu) kÄ tukÅ”u. Å is kods ir ļoti lÄ«dzÄ«gs lookup(), izÅemot to, ka, ja atslÄgai tiek atrasta atbilstÄ«ba, tÄs vÄrtÄ«ba tiek tukÅ”a.
KÄ minÄts iepriekÅ”, kad atslÄga ir ierakstÄ«ta slotÄ, tÄ vairs netiek pÄrvietota. Pat tad, kad elements tiek izdzÄsts no tabulas, atslÄga paliek vietÄ, tÄ vÄrtÄ«ba vienkÄrÅ”i kļūst tukÅ”a. Tas nozÄ«mÄ, ka slota vÄrtÄ«bai nav jÄizmanto atomu rakstÄ«Å”anas operÄcija, jo nav nozÄ«mes, vai paÅ”reizÄjÄ vÄrtÄ«ba ir tukÅ”a vai nÄ ā tÄ tik un tÄ kļūs tukÅ”a.
Jauktabulas izmÄra maiÅa
Hash tabulas izmÄru var mainÄ«t, izveidojot lielÄku tabulu un ievietojot tajÄ netukÅ”us elementus no vecÄs tabulas. Es neieviesu Å”o funkcionalitÄti, jo vÄlÄjos, lai koda paraugs bÅ«tu vienkÄrÅ”s. TurklÄt CUDA programmÄs atmiÅas pieŔķirÅ”ana bieži tiek veikta resursdatora kodÄ, nevis CUDA kodolÄ.
IepriekÅ” minÄtajos funkciju koda fragmentos gpu_hashtable_insert(), _lookup() Šø _delete() vienlaikus apstrÄdÄt vienu atslÄgu-vÄrtÄ«bu pÄri. Un zemÄk gpu_hashtable_insert(), _lookup() Šø _delete() paralÄli apstrÄdÄt pÄru masÄ«vu, katru pÄri atseviÅ”Ä·Ä GPU izpildes pavedienÄ:
// 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);
}
}
BloÄ·ÄÅ”anas izturÄ«ga jaucÄj tabula atbalsta vienlaicÄ«gus ievietoÅ”anu, uzmeklÄÅ”anu un dzÄÅ”anu. TÄ kÄ atslÄgu-vÄrtÄ«bu pÄri vienmÄr atrodas vienÄ no Äetriem stÄvokļiem un atslÄgas nepÄrvietojas, tabula garantÄ pareizÄ«bu pat tad, ja vienlaikus tiek izmantotas dažÄda veida darbÄ«bas.
TomÄr, ja mÄs paralÄli apstrÄdÄsim ievietoÅ”anas un dzÄÅ”anas partiju un ja ievades pÄru masÄ«vÄ ir dublÄtÄs atslÄgas, mÄs nevarÄsim paredzÄt, kuri pÄri āuzvarÄsā ā tie tiks ierakstÄ«ti jaukÅ”anas tabulÄ pÄdÄjie. PieÅemsim, ka mÄs nosaucÄm ievietoÅ”anas kodu ar ievades pÄru masÄ«vu A/0 B/1 A/2 C/3 A/4. Kad kods ir pabeigts, tiek izveidoti pÄri B/1 Šø C/3 ir garantÄti klÄt tabulÄ, bet tajÄ paÅ”Ä laikÄ jebkurÅ” no pÄriem parÄdÄ«sies tajÄ A/0, A/2 vai A/4. Tas var bÅ«t vai nevar bÅ«t problÄma ā tas viss ir atkarÄ«gs no lietojumprogrammas. IespÄjams, jau iepriekÅ” zinÄt, ka ievades masÄ«vÄ nav atslÄgu dublikÄtu, vai arÄ« jums var bÅ«t vienalga, kura vÄrtÄ«ba tika ierakstÄ«ta pÄdÄjÄ.
Ja jums tÄ ir problÄma, jums ir jÄsadala dublikÄtu pÄri dažÄdos CUDA sistÄmas izsaukumos. ProgrammÄ CUDA jebkura darbÄ«ba, kas izsauc kodolu, vienmÄr tiek pabeigta pirms nÄkamÄ kodola izsaukuma (vismaz viena pavediena ietvaros. DažÄdos pavedienos kodoli tiek izpildÄ«ti paralÄli). IepriekÅ” minÄtajÄ piemÄrÄ, ja izsaucat vienu kodolu ar A/0 B/1 A/2 C/3, bet otrs ar A/4, tad atslÄga A iegÅ«s vÄrtÄ«bu 4.
Tagad parunÄsim par to, vai funkcijÄm vajadzÄtu bÅ«t lookup() Šø delete() izmantojiet vienkÄrÅ”u vai nepastÄvÄ«gu rÄdÄ«tÄju uz pÄru masÄ«vu hash tabulÄ. CUDA dokumentÄcija Nosaka, ka:
Kompilators var izvÄlÄties optimizÄt lasÄ«Å”anu un rakstÄ«Å”anu globÄlajÄ vai koplietotajÄ atmiÅÄ... Å Ä«s optimizÄcijas var atspÄjot, izmantojot atslÄgvÄrdu volatile: ... jebkura atsauce uz Å”o mainÄ«go tiek apkopota reÄlÄ atmiÅas lasÄ«Å”anas vai rakstÄ«Å”anas instrukcijÄ.
PareizÄ«bas apsvÄrumi nav jÄpiemÄro volatile. Ja izpildes pavediens izmanto keÅ”atmiÅÄ saglabÄtu vÄrtÄ«bu no agrÄkas lasÄ«Å”anas darbÄ«bas, tad tajÄ tiks izmantota nedaudz novecojusi informÄcija. Bet tomÄr Ŕī ir informÄcija no pareizÄ hash tabulas stÄvokļa noteiktÄ kodola izsaukuma brÄ«dÄ«. Ja jums ir jÄizmanto jaunÄkÄ informÄcija, varat izmantot indeksu volatile, bet tad veiktspÄja nedaudz samazinÄsies: pÄc maniem testiem, dzÄÅ”ot 32 miljonus elementu, Ätrums samazinÄjÄs no 500 miljoniem dzÄÅ”anas/sek lÄ«dz 450 miljoniem dzÄÅ”anas/sek.
ŠŃŠ¾ŠøŠ·Š²Š¾Š“ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ
PÄrbaudÄ par 64 miljonu elementu ievietoÅ”anu un 32 miljonu no tiem dzÄÅ”anu notiek konkurence starp std::unordered_map un GPU praktiski nav hash tabulas:
std::unordered_map pavadÄ«ja 70 691 ms, ievietojot un izÅemot elementus un pÄc tam tos atbrÄ«vojot unordered_map (atbrÄ«voÅ”anÄs no miljoniem elementu aizÅem daudz laika, jo iekÅ”Ä unordered_map tiek veiktas vairÄkas atmiÅas pieŔķirÅ”anas). GodÄ«gi sakot, std:unordered_map pilnÄ«gi atŔķirÄ«gi ierobežojumi. Tas ir viens CPU izpildes pavediens, atbalsta jebkura lieluma atslÄgas vÄrtÄ«bas, labi darbojas ar augstu izmantoÅ”anas lÄ«meni un uzrÄda stabilu veiktspÄju pÄc vairÄkkÄrtÄjas dzÄÅ”anas.
Hash tabulas ilgums GPU un starpprogrammu komunikÄcijai bija 984 ms. Tas ietver laiku, kas pavadÄ«ts, ievietojot tabulu atmiÅÄ un dzÄÅ”ot to (vienreiz tiek pieŔķirts 1 GB atmiÅas, kas CUDA aizÅem kÄdu laiku), ievietojot un dzÄÅ”ot elementus, kÄ arÄ« atkÄrtojot tos. Tiek Åemtas vÄrÄ arÄ« visas kopijas uz videokartes atmiÅu un no tÄs.
PaÅ”as jaucÄj tabulas aizpildÄ«Å”anai bija nepiecieÅ”ams 271 ms. Tas ietver laiku, ko videokarte pavada elementu ievietoÅ”anai un dzÄÅ”anai, un neÅem vÄrÄ laiku, kas pavadÄ«ts kopÄÅ”anai atmiÅÄ un atkÄrtoÅ”anai iegÅ«tajÄ tabulÄ. Ja GPU tabula darbojas ilgu laiku vai ja jaukÅ”anas tabula pilnÄ«bÄ atrodas videokartes atmiÅÄ (piemÄram, lai izveidotu jaucÄjtabulu, kuru izmantos cits GPU kods, nevis centrÄlais procesors), tad testa rezultÄts ir bÅ«tisks.
Videokartes hash tabula demonstrÄ augstu veiktspÄju, pateicoties lielai caurlaidspÄjai un aktÄ«vai paralÄlizÄcijai.
Ierobežojumi
JaucÄj tabulas arhitektÅ«rÄ ir dažas problÄmas, kas jÄÅem vÄrÄ:
LineÄro zondÄÅ”anu apgrÅ«tina klasterizÄcija, kuras dÄļ taustiÅi tabulÄ nav novietoti nevainojami.
Izmantojot Å”o funkciju, taustiÅi netiek noÅemti delete un laika gaitÄ tie pÄrblÄ«vÄ galdu.
TÄ rezultÄtÄ jaucÄj tabulas veiktspÄja var pakÄpeniski pasliktinÄties, it Ä«paÅ”i, ja tÄ pastÄv ilgu laiku un tajÄ ir daudz ievietoÅ”anas un dzÄÅ”anas. Viens no veidiem, kÄ mazinÄt Å”os trÅ«kumus, ir pÄrjaukÅ”ana jaunÄ tabulÄ ar diezgan zemu izmantoÅ”anas lÄ«meni un atkÄrtotas jaukÅ”anas laikÄ filtrÄt noÅemtÄs atslÄgas.
Lai ilustrÄtu aprakstÄ«tÄs problÄmas, es izmantoÅ”u iepriekÅ” minÄto kodu, lai izveidotu tabulu ar 128 miljoniem elementu un cilpu cauri 4 miljoniem elementu, lÄ«dz bÅ«Å”u aizpildÄ«jis 124 miljonus laika niÅ”u (izmantoÅ”anas lÄ«menis aptuveni 0,96). Å eit ir rezultÄtu tabula, katra rinda ir CUDA kodola izsaukums, lai vienÄ hash tabulÄ ievietotu 4 miljonus jaunu elementu:
LietoŔanas līmenis IevietoŔanas ilgums 4 194 304 elementi
0,00
11,608448 ms (361,314798 miljoni atslÄgu/sek.)
0,03
11,751424 ms (356,918799 miljoni atslÄgu/sek.)
0,06
11,942592 ms (351,205515 miljoni atslÄgu/sek.)
0,09
12,081120 ms (347,178429 miljoni atslÄgu/sek.)
0,12
12,242560 ms (342,600233 miljoni atslÄgu/sek.)
0,16
12,396448 ms (338,347235 miljoni atslÄgu/sek.)
0,19
12,533024 ms (334,660176 miljoni atslÄgu/sek.)
0,22
12,703328 ms (330,173626 miljoni atslÄgu/sek.)
0,25
12,884512 ms (325,530693 miljoni atslÄgu/sek.)
0,28
13,033472 ms (321,810182 miljoni atslÄgu/sek.)
0,31
13,239296 ms (316,807174 miljoni atslÄgu/sek.)
0,34
13,392448 ms (313,184256 miljoni atslÄgu/sek.)
0,37
13,624000 ms (307,861434 miljoni atslÄgu/sek.)
0,41
13,875520 ms (302,280855 miljoni atslÄgu/sek.)
0,44
14,126528 ms (296,909756 miljoni atslÄgu/sek.)
0,47
14,399328 ms (291,284699 miljoni atslÄgu/sek.)
0,50
14,690304 ms (285,515123 miljoni atslÄgu/sek.)
0,53
15,039136 ms (278,892623 miljoni atslÄgu/sek.)
0,56
15,478656 ms (270,973402 miljoni atslÄgu/sek.)
0,59
15,985664 ms (262,379092 miljoni atslÄgu/sek.)
0,62
16,668673 ms (251,627968 miljoni atslÄgu/sek.)
0,66
17,587200 ms (238,486174 miljoni atslÄgu/sek.)
0,69
18,690048 ms (224,413765 miljoni atslÄgu/sek.)
0,72
20,278816 ms (206,831789 miljoni atslÄgu/sek.)
0,75
22,545408 ms (186,038058 miljoni atslÄgu/sek.)
0,78
26,053312 ms (160,989275 miljoni atslÄgu/sek.)
0,81
31,895008 ms (131,503463 miljoni atslÄgu/sek.)
0,84
42,103294 ms (99,619378 miljoni atslÄgu/sek.)
0,87
61,849056 ms (67,815164 miljoni atslÄgu/sek.)
0,90
105,695999 ms (39,682713 miljoni atslÄgu/sek.)
0,94
240,204636 ms (17,461378 miljoni atslÄgu/sek.)
Palielinoties izmantoÅ”anai, veiktspÄja samazinÄs. VairumÄ gadÄ«jumu tas nav vÄlams. Ja lietojumprogramma ievieto elementus tabulÄ un pÄc tam tos izmet (piemÄram, saskaitot vÄrdus grÄmatÄ), tad tÄ nav problÄma. Bet, ja lietojumprogramma izmanto ilgstoÅ”as āāāājaucÄjtabulas (piemÄram, grafiskajÄ redaktorÄ, lai saglabÄtu netukÅ”as attÄlu daļas, kurÄs lietotÄjs bieži ievieto un dzÄÅ” informÄciju), Ŕī darbÄ«ba var bÅ«t problemÄtiska.
Un izmÄrÄ«ja hash tabulas zondÄÅ”anas dziļumu pÄc 64 miljoniem ievietoÅ”anas (izmantoÅ”anas koeficients 0,5). VidÄjais dziļums bija 0,4774, tÄpÄc lielÄkÄ daļa taustiÅu atradÄs vai nu labÄkajÄ iespÄjamajÄ slotÄ, vai viena slota attÄlumÄ no labÄkÄs pozÄ«cijas. MaksimÄlais zondÄÅ”anas dziļums bija 60.
PÄc tam es mÄrÄ«ju zondÄÅ”anas dziļumu uz galda ar 124 miljoniem ieliktÅu (izmantoÅ”anas koeficients 0,97). VidÄjais dziļums jau bija 10,1757, bet maksimÄlais - 6474 (!!). LineÄrÄs sensora veiktspÄja ievÄrojami samazinÄs pie augsta izmantoÅ”anas lÄ«meÅa.
VislabÄk ir saglabÄt zemu Ŕīs hash tabulas izmantoÅ”anas lÄ«meni. Bet tad mÄs palielinÄm veiktspÄju uz atmiÅas patÄriÅa rÄÄ·ina. Par laimi, 32 bitu atslÄgu un vÄrtÄ«bu gadÄ«jumÄ to var attaisnot. Ja iepriekÅ” minÄtajÄ piemÄrÄ tabulÄ ar 128 miljoniem elementu saglabÄjam izmantoÅ”anas koeficientu 0,25, tad tajÄ varam ievietot ne vairÄk kÄ 32 miljonus elementu, un tiks zaudÄti atlikuÅ”ie 96 miljoni slotu - 8 baiti katram pÄrim. , 768 MB zaudÄtas atmiÅas.
LÅ«dzu, Åemiet vÄrÄ, ka mÄs runÄjam par videokartes atmiÅas zudumu, kas ir vÄrtÄ«gÄks resurss nekÄ sistÄmas atmiÅa. Lai gan lielÄkajai daļai mÅ«sdienu galddatoru grafisko karÅ”u, kas atbalsta CUDA, ir vismaz 4 GB atmiÅa (raksta tapÅ”anas brÄ«dÄ« NVIDIA 2080 Ti ir 11 GB), zaudÄt Å”Ädas summas tomÄr nebÅ«tu prÄtÄ«gÄkais lÄmums.
VÄlÄk rakstÄ«Å”u vairÄk par jaucÄjtabulu izveidi videokartÄm, kurÄm nav problÄmu ar zondÄÅ”anas dziļumu, kÄ arÄ« veidiem, kÄ atkÄrtoti izmantot izdzÄstos slotus.
Zondes dziļuma mÄrÄ«Å”ana
Lai noteiktu atslÄgas pÄrbaudes dziļumu, mÄs varam iegÅ«t atslÄgas jaucÄjkodu (tÄ ideÄlo tabulas indeksu) no tÄs faktiskÄ tabulas indeksa:
// get_key_index() -> index of key in hash table
uint32_t probelength = (get_key_index(key) - hash(key)) & (hashtablecapacity-1);
TÄ kÄ divi divi komplementa binÄrie skaitļi ir burvÄ«gi un ka jaukÅ”anas tabulas ietilpÄ«ba ir divi ar pakÄpju divi, Ŕī pieeja darbosies pat tad, ja atslÄgas indekss tiek pÄrvietots uz tabulas sÄkumu. PaÅemsim atslÄgu, kas ir sajaukta ar 1, bet tiek ievietota slotÄ 3. Tad tabulai ar ietilpÄ«bu 4 mÄs iegÅ«stam (3 ā 1) & 3, kas ir lÄ«dzvÄrtÄ«gs 2.
SecinÄjums
Ja jums ir jautÄjumi vai komentÄri, lÅ«dzu, rakstiet man uz e-pastu Twitter vai atveriet jaunu tÄmu krÄtuves.
Šis kods tika uzrakstīts, iedvesmojoties no lieliskiem rakstiem:
NÄkotnÄ es turpinÄÅ”u rakstÄ«t par video karÅ”u hash tabulu ievieÅ”anu un analizÄt to veiktspÄju. Manos plÄnos ietilpst Ä·Äde, Robina Huda jaukÅ”ana un dzeguzes jaukÅ”ana, izmantojot atomu operÄcijas datu struktÅ«rÄs, kas ir draudzÄ«gas GPU.