Tabella sempliċi tal-hash għall-GPU

Tabella sempliċi tal-hash għall-GPU
Poġġejtha fuq Github proġett ġdid A Simple GPU Hash Table.

Hija tabella hash GPU sempliċi li kapaċi tipproċessa mijiet ta 'miljuni ta' inserzjonijiet kull sekonda. Fuq il-laptop tiegħi NVIDIA GTX 1060, il-kodiċi jdaħħal 64 miljun par ta 'valur ewlieni ġenerat bl-addoċċ f'madwar 210 ms u jneħħi 32 miljun par f'madwar 64 ms.

Jiġifieri, il-veloċità fuq laptop hija madwar 300 miljun inserzjoni/sek u 500 miljun tħassir/sec.

It-tabella hija miktuba f'CUDA, għalkemm l-istess teknika tista' tiġi applikata għal HLSL jew GLSL. L-implimentazzjoni għandha bosta limitazzjonijiet biex tiżgura prestazzjoni għolja fuq karta tal-vidjo:

  • Ċwievet ta '32-bit biss u l-istess valuri huma pproċessati.
  • It-tabella tal-hash għandha daqs fiss.
  • U dan id-daqs għandu jkun ugwali għal tnejn għall-qawwa.

Għaċ-ċwievet u l-valuri, trid tirriżerva markatur delimitatur sempliċi (fil-kodiċi ta 'hawn fuq dan huwa 0xffffffff).

Tabella hash mingħajr serraturi

It-tabella hash tuża indirizzar miftuħ ma ' probing lineari, jiġifieri, hija sempliċement firxa ta 'pari ta' valuri ewlenin li hija maħżuna fil-memorja u għandha prestazzjoni ta 'cache superjuri. L-istess ma jistax jingħad għall-katina, li jinvolvi t-tfittxija għal pointer f'lista konnessa. Tabella hash hija firxa sempliċi li taħżen elementi KeyValue:

struct KeyValue
{
    uint32_t key;
    uint32_t value;
};

Id-daqs tat-tabella huwa qawwa ta 'tnejn, mhux numru ewlieni, għaliex istruzzjoni waħda veloċi hija biżżejjed biex tapplika l-maskra pow2/AND, iżda l-operatur tal-modulu huwa ħafna aktar bil-mod. Dan huwa importanti fil-każ ta 'sondar lineari, peress li f'tfittxija ta' tabella lineari l-indiċi tas-slots għandu jkun imgeżwer f'kull slot. U bħala riżultat, l-ispiża tal-operazzjoni hija miżjuda modulo f'kull slot.

It-tabella taħżen biss iċ-ċavetta u l-valur għal kull element, mhux hash taċ-ċavetta. Peress li t-tabella taħżen biss ċwievet 32-bit, il-hash huwa kkalkulat malajr ħafna. Il-kodiċi ta 'hawn fuq juża l-hash Murmur3, li jwettaq biss ftit shifts, XORs u multiplikazzjoni.

It-tabella tal-hash tuża tekniki ta 'protezzjoni tal-illokkjar li huma indipendenti mill-ordni tal-memorja. Anke jekk xi operazzjonijiet ta 'kitba jfixklu l-ordni ta' operazzjonijiet oħra bħal dawn, it-tabella tal-hash xorta se żżomm l-istat korrett. Aħna ser nitkellmu dwar dan hawn taħt. It-teknika taħdem tajjeb bil-kards tal-vidjo li jmexxu eluf ta 'ħjut fl-istess ħin.

Iċ-ċwievet u l-valuri fit-tabella tal-hash huma inizjalizzati biex jitbattlu.

Il-kodiċi jista 'jiġi modifikat biex jimmaniġġja ċwievet u valuri ta' 64-bit ukoll. Iċ-ċwievet jeħtieġu operazzjonijiet atomiċi ta' qari, tikteb u tqabbil u tpartit. U l-valuri jeħtieġu operazzjonijiet atomiċi ta 'qari u kitba. Fortunatament, f'CUDA, operazzjonijiet ta 'qari u kitba għal valuri ta' 32 u 64 bit huma atomiċi sakemm ikunu allinjati b'mod naturali (ara hawn taħt). hawn), u karti tal-vidjo moderni jappoġġjaw operazzjonijiet ta 'tqabbil u skambju atomiċi ta' 64 bit. Naturalment, meta timxi għal 64 bit, il-prestazzjoni se tonqos ftit.

Stat tabella hash

Kull par key-value f'tabella hash jista' jkollu wieħed minn erba' stati:

  • Iċ-ċavetta u l-valur huma vojta. F'dan l-istat, it-tabella hash hija inizjalizzata.
  • Iċ-ċavetta ġiet miktuba, iżda l-valur għadu ma ġiex imniżżel. Jekk ħajt ieħor bħalissa qed jaqra d-dejta, imbagħad jirritorna vojta. Dan huwa normali, l-istess ħaġa tkun ġara kieku ħajt ieħor ta 'eżekuzzjoni kien ħadem ftit qabel, u qed nitkellmu dwar struttura ta' data konkorrenti.
  • Kemm iċ-ċavetta kif ukoll il-valur huma rreġistrati.
  • Il-valur huwa disponibbli għal ħjut oħra ta 'eżekuzzjoni, iżda ċ-ċavetta għadha mhix. Dan jista 'jiġri minħabba li l-mudell ta' programmar CUDA għandu mudell ta 'memorja ordnat b'mod laxk. Dan huwa normali; fi kwalunkwe każ, iċ-ċavetta għadha vojta, anke jekk il-valur m'għadux hekk.

Sfumatura importanti hija li ladarba ċ-ċavetta tkun inkitbet fis-slot, ma tibqax tiċċaqlaq - anki jekk iċ-ċavetta titħassar, se nitkellmu dwar dan hawn taħt.

Il-kodiċi tal-hash table anke jaħdem ma 'mudelli ta' memorja ordnati b'mod laxk li fihom l-ordni li fiha tinqara u tinkiteb il-memorja mhix magħrufa. Hekk kif inħarsu lejn l-inserzjoni, it-tiftix u t-tħassir f'tabella hash, ftakar li kull par ta 'valur-ċavetta jinsab f'wieħed mill-erba' stati deskritti hawn fuq.

Daħħal f'tabella hash

Il-funzjoni CUDA li ddaħħal pari ewlenin-valur f'tabella hash tidher bħal din:

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

Biex tiddaħħal ċavetta, il-kodiċi jtenni permezz tal-array tal-hash table li jibda bil-hash taċ-ċavetta mdaħħla. Kull slot fil-firxa jwettaq operazzjoni atomika ta 'tqabbil u tpartit li tqabbel iċ-ċavetta f'dak is-slot ma' vojta. Jekk jinstab nuqqas ta 'qbil, iċ-ċavetta fl-islott tiġi aġġornata biċ-ċavetta mdaħħla, u mbagħad iċ-ċavetta tal-islott oriġinali tiġi rritornata. Jekk din iċ-ċavetta oriġinali kienet vojta jew imqabbla maċ-ċavetta mdaħħla, allura l-kodiċi sab slot adattat għall-inserzjoni u daħħal il-valur imdaħħal fis-slot.

Jekk f'sejħa tal-qalba waħda gpu_hashtable_insert() hemm elementi multipli bl-istess ċavetta, allura kwalunkwe wieħed mill-valuri tagħhom jista 'jinkiteb fl-islott taċ-ċavetta. Dan huwa meqjus bħala normali: waħda mill-kitba tal-valur ewlieni matul is-sejħa tirnexxi, iżda peress li dan kollu jseħħ b'mod parallel f'diversi ħjut ta 'eżekuzzjoni, ma nistgħux inbassru liema kitba tal-memorja se tkun l-aħħar waħda.

Lookup tabella hash

Kodiċi għat-tiftix taċ-ċwievet:

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

Biex issib il-valur ta 'ċavetta maħżuna f'tabella, aħna ngħaddu mill-firxa li tibda bil-hash taċ-ċavetta li qed infittxu. F'kull slot, aħna niċċekkjaw jekk iċ-ċavetta hijiex dik li qed infittxu, u jekk iva, nirritornaw il-valur tagħha. Aħna niċċekkjaw ukoll jekk iċ-ċavetta hijiex vojta, u jekk iva, nabbandunaw it-tfittxija.

Jekk ma nistgħux insibu ċ-ċavetta, il-kodiċi jirritorna valur vojt.

Dawn l-operazzjonijiet ta’ tfittxija kollha jistgħu jsiru fl-istess ħin permezz ta’ inserzjonijiet u tħassir. Kull par fit-tabella se jkollu wieħed mill-erba 'stati deskritti hawn fuq għall-fluss.

Tħassir f'tabella hash

Kodiċi għat-tħassir taċ-ċwievet:

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

It-tħassir ta 'ċavetta jsir b'mod mhux tas-soltu: inħallu ċ-ċavetta fit-tabella u nimmarkaw il-valur tagħha (mhux iċ-ċavetta nnifisha) bħala vojta. Dan il-kodiċi huwa simili ħafna għal lookup(), ħlief li meta tinstab taqbila fuq ċavetta, tagħmel il-valur tagħha vojta.

Kif imsemmi hawn fuq, ladarba ċavetta tinkiteb fi slot, ma tibqax imċaqlaq. Anke meta element jitħassar mit-tabella, iċ-ċavetta tibqa' f'postha, il-valur tagħha sempliċement isir vojt. Dan ifisser li m'għandniex bżonn nużaw operazzjoni ta 'kitba atomika għall-valur tal-islott, għax ma jimpurtax jekk il-valur kurrenti huwiex vojt jew le - xorta se jsir vojt.

Ridimensjonar tabella hash

Tista 'tbiddel id-daqs ta' tabella hash billi toħloq tabella akbar u ddaħħal elementi mhux vojta mit-tabella l-antika fiha. Ma implimentajtx din il-funzjonalità għax ridt li nżomm il-kodiċi tal-kampjun sempliċi. Barra minn hekk, fil-programmi CUDA, l-allokazzjoni tal-memorja ħafna drabi ssir fil-kodiċi ospitanti aktar milli fil-kernel CUDA.

Fl-artikolu Tabella Hash Free Wait-Free Lock jiddeskrivi kif timmodifika tali struttura ta' data protetta b'lock.

Kompetittività

Fis-snippets tal-kodiċi tal-funzjoni t'hawn fuq gpu_hashtable_insert(), _lookup() и _delete() jipproċessa par ta' valur-ċavetta wieħed kull darba. U aktar baxxi gpu_hashtable_insert(), _lookup() и _delete() tipproċessa firxa ta' pari b'mod parallel, kull par f'ħajt separat ta' eżekuzzjoni tal-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);
    }
}

It-tabella tal-hash reżistenti għas-serratura tappoġġja inserzjonijiet, tiftix, u tħassir konkorrenti. Minħabba li l-pari ewlenin-valur huma dejjem f'wieħed minn erba 'stati u ċ-ċwievet ma jiċċaqilqux, it-tabella tiggarantixxi l-korrettezza anke meta jintużaw tipi differenti ta' operazzjonijiet simultanjament.

Madankollu, jekk nipproċessaw lott ta 'inserzjonijiet u tħassir b'mod parallel, u jekk l-array ta' input ta 'pari jkun fih ċwievet duplikati, allura ma nkunux nistgħu nbassru liema pari se "jirbħu"—se jinkitbu fit-tabella hash l-aħħar. Ejja ngħidu aħna sejjaħ il-kodiċi ta 'inserzjoni ma' firxa ta 'input ta' pari A/0 B/1 A/2 C/3 A/4. Meta l-kodiċi jitlesta, pari B/1 и C/3 huma garantiti li jkunu preżenti fit-tabella, iżda fl-istess ħin kwalunkwe mill-pari se jidhru fiha A/0, A/2 jew A/4. Dan jista 'jew ma jistax ikun problema - dan kollu jiddependi fuq l-applikazzjoni. Tista' tkun taf minn qabel li m'hemm l-ebda ċwievet duplikati fl-array tad-dħul, jew tista' ma jimpurtax liema valur inkiteb l-aħħar.

Jekk din hija problema għalik, allura għandek bżonn tissepara l-pari duplikati f'sejħiet tas-sistema CUDA differenti. F'CUDA, kwalunkwe operazzjoni li ssejjaħ il-kernel dejjem titlesta qabel is-sejħa tal-kernel li jmiss (mill-inqas f'ħajt wieħed. F'ħjut differenti, il-kernels huma esegwiti b'mod parallel). Fl-eżempju ta 'hawn fuq, jekk issejjaħ għadma waħda bi A/0 B/1 A/2 C/3, u l-oħra ma A/4, imbagħad iċ-ċavetta A se tikseb il-valur 4.

Issa ejja nitkellmu dwar jekk il-funzjonijiet għandhomx lookup() и delete() uża pointer sempliċi jew volatili għal firxa ta 'pari fit-tabella hash. Dokumentazzjoni CUDA Jiddikjara li:

Il-kompilatur jista' jagħżel li jottimizza l-qari u l-kitba fil-memorja globali jew kondiviża... Dawn l-ottimizzazzjonijiet jistgħu jiġu diżattivati ​​billi tuża l-kelma prinċipali volatile: ... kull referenza għal din il-varjabbli hija kkumpilata f'istruzzjoni ta' memorja reali ta' qari jew tikteb.

Konsiderazzjonijiet ta' korrettezza ma jeħtiġux applikazzjoni volatile. Jekk il-ħajt ta 'eżekuzzjoni juża valur cache minn operazzjoni ta' qari preċedenti, allura jkun qed juża informazzjoni kemmxejn skaduta. Iżda xorta waħda, din hija informazzjoni mill-istat korrett tat-tabella hash f'ċertu mument tas-sejħa tal-kernel. Jekk għandek bżonn tuża l-aħħar informazzjoni, tista 'tuża l-indiċi volatile, iżda mbagħad il-prestazzjoni se tonqos ftit: skond it-testijiet tiegħi, meta tħassar 32 miljun element, il-veloċità naqset minn 500 miljun tħassir/sec għal 450 miljun tħassir/sec.

Produttività

Fit-test biex jiddaħħlu 64 miljun element u jitħassru 32 miljun minnhom, kompetizzjoni bejn std::unordered_map u prattikament m'hemm l-ebda tabella hash għall-GPU:

Tabella sempliċi tal-hash għall-GPU
std::unordered_map qattgħu 70 ms idaħħlu u jneħħu elementi u mbagħad ħelishom unordered_map (li teħles minn miljuni ta’ elementi tieħu ħafna ħin, għax ġewwa unordered_map isiru allokazzjonijiet multipli tal-memorja). Onestament speaking, std:unordered_map restrizzjonijiet kompletament differenti. Huwa ħajt ta 'eżekuzzjoni ta' CPU wieħed, jappoġġja valuri ewlenin ta 'kull daqs, jaħdem tajjeb b'rati ta' utilizzazzjoni għolja, u juri prestazzjoni stabbli wara tħassir multipli.

It-tul tat-tabella tal-hash għall-GPU u l-komunikazzjoni bejn il-programmi kien 984 ms. Dan jinkludi l-ħin imqatta 'jpoġġi t-tabella fil-memorja u tħassarha (l-allokazzjoni ta' 1 GB ta 'memorja darba, li tieħu xi żmien f'CUDA), id-dħul u t-tħassir ta' elementi, u l-iterazzjoni fuqhom. Il-kopji kollha lejn u mill-memorja tal-kard tal-vidjo huma wkoll ikkunsidrati.

It-tabella tal-hash innifisha ħadet 271 ms biex titlesta. Dan jinkludi l-ħin li l-kard tal-vidjo ddaħħal u tħassar elementi, u ma jqisx il-ħin mgħoddi biex tikkopja fil-memorja u tgħaddi fuq it-tabella li tirriżulta. Jekk it-tabella tal-GPU tgħix għal żmien twil, jew jekk it-tabella tal-hash tinsab kompletament fil-memorja tal-kard tal-vidjo (per eżempju, biex tinħoloq tabella tal-hash li se tintuża minn kodiċi GPU ieħor u mhux mill-proċessur ċentrali), allura ir-riżultat tat-test huwa rilevanti.

It-tabella tal-hash għal kard tal-vidjo turi prestazzjoni għolja minħabba throughput għoli u parallelizzazzjoni attiva.

Limitazzjonijiet

L-arkitettura tal-hash table għandha ftit kwistjonijiet li għandek tkun konxju minnhom:

  • L-istħarriġ lineari huwa mxekkel minn raggruppament, li jikkawża li ċ-ċwievet fit-tabella jitqiegħdu inqas minn perfettament.
  • Iċ-ċwievet ma jitneħħewx bl-użu tal-funzjoni delete u maż-żmien iħammġu l-mejda.

Bħala riżultat, il-prestazzjoni ta 'tabella hash tista' gradwalment tiddegrada, speċjalment jekk teżisti għal żmien twil u għandha inserzjonijiet u tħassir numerużi. Mod wieħed biex jittaffew dawn l-iżvantaġġi huwa li tirrehash f'tabella ġdida b'rata ta 'utilizzazzjoni pjuttost baxxa u tiffiltra ċ-ċwievet imneħħija waqt ir-rehashing.

Biex nispjega l-kwistjonijiet deskritti, ser nuża l-kodiċi ta 'hawn fuq biex noħloq tabella b'128 miljun element u ngħaddi minn 4 miljun element sakemm imlejt 124 miljun slots (rata ta' utilizzazzjoni ta 'madwar 0,96). Hawnhekk hawn it-tabella tar-riżultati, kull ringiela hija sejħa tal-kernel CUDA biex tiddaħħal 4 miljun element ġdid f'tabella hash waħda:

Rata ta 'użu
Tul ta' inserzjoni 4 elementi

0,00
11,608448 ms (361,314798 miljun ċavetta/sek.)

0,03
11,751424 ms (356,918799 miljun ċavetta/sek.)

0,06
11,942592 ms (351,205515 miljun ċavetta/sek.)

0,09
12,081120 ms (347,178429 miljun ċavetta/sek.)

0,12
12,242560 ms (342,600233 miljun ċavetta/sek.)

0,16
12,396448 ms (338,347235 miljun ċavetta/sek.)

0,19
12,533024 ms (334,660176 miljun ċavetta/sek.)

0,22
12,703328 ms (330,173626 miljun ċavetta/sek.)

0,25
12,884512 ms (325,530693 miljun ċavetta/sek.)

0,28
13,033472 ms (321,810182 miljun ċavetta/sek.)

0,31
13,239296 ms (316,807174 miljun ċavetta/sek.)

0,34
13,392448 ms (313,184256 miljun ċavetta/sek.)

0,37
13,624000 ms (307,861434 miljun ċavetta/sek.)

0,41
13,875520 ms (302,280855 miljun ċavetta/sek.)

0,44
14,126528 ms (296,909756 miljun ċavetta/sek.)

0,47
14,399328 ms (291,284699 miljun ċavetta/sek.)

0,50
14,690304 ms (285,515123 miljun ċavetta/sek.)

0,53
15,039136 ms (278,892623 miljun ċavetta/sek.)

0,56
15,478656 ms (270,973402 miljun ċavetta/sek.)

0,59
15,985664 ms (262,379092 miljun ċavetta/sek.)

0,62
16,668673 ms (251,627968 miljun ċavetta/sek.)

0,66
17,587200 ms (238,486174 miljun ċavetta/sek.)

0,69
18,690048 ms (224,413765 miljun ċavetta/sek.)

0,72
20,278816 ms (206,831789 miljun ċavetta/sek.)

0,75
22,545408 ms (186,038058 miljun ċavetta/sek.)

0,78
26,053312 ms (160,989275 miljun ċavetta/sek.)

0,81
31,895008 ms (131,503463 miljun ċavetta/sek.)

0,84
42,103294 ms (99,619378 miljun ċavetta/sek.)

0,87
61,849056 ms (67,815164 miljun ċavetta/sek.)

0,90
105,695999 ms (39,682713 miljun ċavetta/sek.)

0,94
240,204636 ms (17,461378 miljun ċavetta/sek.)

Hekk kif l-utilizzazzjoni tiżdied, il-prestazzjoni tonqos. Dan mhux mixtieq f'ħafna każijiet. Jekk applikazzjoni ddaħħal elementi f'tabella u mbagħad tarmihom (pereżempju, meta tgħodd il-kliem fi ktieb), allura din mhix problema. Imma jekk l-applikazzjoni tuża tabella tal-hash ta’ ħajja twila (pereżempju, f’editur tal-grafika biex taħżen partijiet ta’ immaġini mhux vojta fejn l-utent spiss idaħħal u jħassar informazzjoni), allura din l-imġieba tista’ tkun problematika.

U kejjel il-fond tal-istħarriġ tal-hash table wara 64 miljun inserzjoni (fattur ta 'utilizzazzjoni 0,5). Il-fond medju kien 0,4774, għalhekk il-biċċa l-kbira taċ-ċwievet kienu jew fl-aħjar slot possibbli jew slot wieħed 'il bogħod mill-aħjar pożizzjoni. Il-fond massimu tal-ħoss kien 60.

Imbagħad imkejjel il-fond tal-istħarriġ fuq mejda b'124 miljun inserzjoni (fattur ta 'utilizzazzjoni 0,97). Il-fond medju kien diġà 10,1757, u l-massimu - 6474 (!!). Il-prestazzjoni ta 'sensing lineari tinżel b'mod sinifikanti b'rati ta' utilizzazzjoni għolja.

Huwa aħjar li żżomm ir-rata ta 'utilizzazzjoni ta' din il-hash table baxxa. Imma mbagħad inżidu l-prestazzjoni għad-detriment tal-konsum tal-memorja. Fortunatament, fil-każ ta 'ċwievet u valuri 32-bit, dan jista' jkun iġġustifikat. Jekk fl-eżempju ta 'hawn fuq, f'tabella b'128 miljun element, inżommu l-fattur ta' utilizzazzjoni ta '0,25, allura nistgħu npoġġu mhux aktar minn 32 miljun element fiha, u s-96 miljun slots li jifdal jintilfu - 8 bytes għal kull par , 768 MB ta' memorja mitlufa.

Jekk jogħġbok innota li qed nitkellmu dwar it-telf tal-memorja tal-kard tal-vidjo, li hija riżorsa aktar siewja mill-memorja tas-sistema. Għalkemm il-biċċa l-kbira tal-karti tal-grafika tad-desktop moderni li jappoġġaw CUDA għandhom mill-inqas 4 GB ta 'memorja (fil-ħin tal-kitba, l-NVIDIA 2080 Ti għandha 11 GB), xorta ma tkunx l-aktar deċiżjoni għaqlija li jitilfu tali ammonti.

Aktar tard se nikteb aktar dwar il-ħolqien ta 'tabelli tal-hash għal kards tal-vidjo li m'għandhomx problemi bil-fond tal-istħarriġ, kif ukoll modi kif terġa' tuża slots imħassra.

Kejl tal-fond tal-ħoss

Biex niddeterminaw il-fond ta' probing ta' ċavetta, nistgħu niġbdu l-hash taċ-ċavetta (l-indiċi tat-tabella ideali tagħha) mill-indiċi attwali tat-tabella tagħha:

// get_key_index() -> index of key in hash table
uint32_t probelength = (get_key_index(key) - hash(key)) & (hashtablecapacity-1);

Minħabba l-maġija tan-numri binarji tal-kompliment tat-tnejn ta 'żewġ u l-fatt li l-kapaċità tat-tabella tal-hash hija tnejn għall-qawwa ta' tnejn, dan l-approċċ se jaħdem anke meta l-indiċi ewlieni jitmexxa għall-bidu tat-tabella. Ejja nieħdu ċavetta li hashed għal 1, iżda tiddaħħal fis-slot 3. Imbagħad għal tabella b'kapaċità 4 irridu nġibu (3 — 1) & 3, li hija ekwivalenti għal 2.

Konklużjoni

Jekk għandek mistoqsijiet jew kummenti, jekk jogħġbok ibgħatli email fuq twitter jew tiftaħ suġġett ġdid fi repożitorji.

Dan il-kodiċi nkiteb taħt ispirazzjoni minn artikoli eċċellenti:

Fil-futur, se nkompli nikteb dwar l-implimentazzjonijiet tal-hash table għall-kards tal-vidjo u tanalizza l-prestazzjoni tagħhom. Il-pjanijiet tiegħi jinkludu chaining, Robin Hood hashing, u cuckoo hashing bl-użu ta 'operazzjonijiet atomiċi fi strutturi tad-dejta li huma faċli għall-GPU.

Sors: www.habr.com

Żid kumment