Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem c++ více vláken, stejná cache

Zdravím,

píšu program, mám zde frontu úkolů, a potom vlákna, které mají frontu obsluhovat.

Problém nastává v tom, že fronta úkolů je globální proměnná, a když program běží ve více vláknech, tak každé vlákno, co upraví tu frontu tím způsobí, že u druhého vlákna přestane platit cache, a program se tím neskutečně zpomalí.

Nějak by to chtělo zajistit aby všechny vlákna používali stejnou cache. Ať data nemusí načítat přímo z paměti.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
BTW. vies co to je critical section? Ak nie tak to je ta chyba.
MM.. 15.05.2016 19:53
MM..
Vím co je to kritická sekce. Program funguje bez problému, nejsou tam žádné chyby. Jen je pomalejší…
Fleee 15.05.2016 20:43
Fleee
Cache funguje na HW urovni a nezaujimaju ju ziadne vlakna. Ked ti program nefunguje tak jak ma alebo…
MM.. 16.05.2016 12:11
MM..
#include <iostream> #include <stdio.h> #include <pthread.h> #include <time.h> #define THREADS_NUMBER…
Fleee 16.05.2016 17:41
Fleee
Ak tvoj program vyzerá podobne, tak potom áno, v spomalení zohráva svoju rolu aj cache na jednotlivý… poslední
los 16.05.2016 21:37
los

Vím co je to kritická sekce.

Program funguje bez problému, nejsou tam žádné chyby. Jen je pomalejší, když vytvořím více než jedno vlákno.

int promenna = 0;

void vlakno(){
while(nejaka podmínka){
...nejaky kod;

LOCK();
promenna = promenna + 1;
UNLOCK();
}
}

Pokud mám jedno vlákno, tak to jedno vlákno má uloženou proměnnou "promenna" v cachce a nemusí sahat vůbec do paměti. Program je pak o něco rychlejší kvůli tomu.

Když mám dvě vlákna, tak každé vlákno má svoji vlastní cachce. Pokaždé když se tedy změní proměnná "promenna", musí ji jedno vlákno uložit do paměti, a druhé má neplatnou cache, a tak ji musí zase načíst z paměti. Program je potom mnohem pomalejší. (cache je rychlejší než paměť).

Proto by bylo vhodné nějak zařídit aby ty sdílené proměnné byli i ve stejné cache.

#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <time.h>

#define THREADS_NUMBER 4

using namespace std;


pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
int x = 0;

//vlakno
void * func(void * nic){
    while(x < 1000000){
        pthread_mutex_lock(&mx);
        x = x + 1;
        pthread_mutex_unlock(&mx);
    }
}

// The main progam.
int main() {
    clock_t t1,t2;
    t1=clock();
    //vytvoreni vlaken
    pthread_t main_thread[THREADS_NUMBER];
    for(int i = 0; i < THREADS_NUMBER; i++){
        pthread_create(&main_thread[i], NULL, &func, (void*)&x);
    }
    //cekani na dokonceni prace vlaken
    for(int i = 0; i < THREADS_NUMBER; i++){
        pthread_join(main_thread[i], NULL);
    }
    t2=clock();
    cout << ((float)t2-(float)t1)  << endl;
    return 0;
}

Příklad kódu na kterým je to nejvíce vidět.

pokaždé jsou v programu 4 vlákna, všechny udělají stejný počet operací, ale pokud program pustíte na jednom jádře, tak bude výrazně rychlejší než když povolíte všechny jádra. (správce úloh >> podrobnosti >> spřažení >> jedno jádro pro příkazovej řáek ze kterýho to budete spouštět.)

Asi jsem se minule někde upsal, ale myslel jsem to tak, že každé jádro má vlastní cache.
Když tedy běží čtyři vlákna na jednom jádře procesoru - sdílí stejnou cache.
Když běží čtyři vlákna na čtyřech jádrech procesoru - mají každou svoji vlastní cache.

Ještě k tomu, když bych snad vytvářel vlákna nějak špatně, a kvůli tomu by se to zpomalilo. Proč to zpomalení není vidět v případě, kdy program běží na jednom jádře procesoru (jedna cachce pro všechny vlákna) a vytváří 10 000 vláken ??

Ak tvoj program vyzerá podobne, tak potom áno, v spomalení zohráva svoju rolu aj cache na jednotlivých jadrách CPU. Všetky vlákna prakticky neustále súperia o vstup do kritickej sekcie. V tejto ukážke vlákna v podstate nerobia nič iné, než len sa medzi sebou synchronizujú.

Za normálnych okolností spracovanie z fronty vyzerá tak, že sa z nej vyberú dáta o úlohe a tá sa potom spracuje samostatne, bez potreby ďalšej synchronizácie. Synchronizovaný je len výber z fronty, ktorý zvyčajne trvá oproti spracovaniu zanedbateľný čas.

Ak sa nevieš vyhnúť tomu, aby sa tvoj program podobal tejto ukážke, tak to zadanie potom nie je vhodné na paralelizovanie a bude lepšie to spracovávať sekvenčne.

Zpět do poradny Odpovědět na původní otázku Nahoru