2012-04-07 12 views
8

Czy ktoś ma doświadczenie z dość nowym std::async? Aktualnie wdrażamy równoległy parser plików, który odczytuje fragment pliku i przekazuje ten fragment do funkcji asynchronicznej.Zachowanie GCC z std :: async (std :: launch :: async) vs. zachowanie Clanga

Używanie Clang (v3.0) w ten sposób działa naprawdę dobrze przy domyślnych zasadach std::async (zależnych od implementacji). Na dwurdzeniowym komputerze wystrzeliwuje do 4 wątków, co działa bardzo dobrze.

Ale z GCC (v4.7), wątek odczytu pliku nie spawnuje żadnych nowych wątków, przez co program na końcu jest całkowicie sekwencyjny.

Korzystanie z std::launch::async, obie wersje są prawie robi to samo (co powinno być w tym przypadku).

Czy ktoś wie, jaki jest stan aktualnych możliwości gwintowania C++ w GCC? A może to błąd w naszej implementacji?

krótki kod:

while (readNewChunk()) { 
    Chunk &chunk = fileReader_.getChunk(); //reading the file 
    ChunkLoader *chunkLoader = new ChunkLoader(); 
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader); 
    dictCreationFutures_.push_back(std::move(ftr)); 
} 
+0

Naprawdę polecam użycie funkcji Boost. To nie będzie duży skok do właściwej obsługi C++ 11. Nowe modele wątków w C++ 11 wymagają innego układu pamięci niż GCC lub MSVC i nie są one zaimplementowane tak naprawdę. –

Odpowiedz

15

Zachowanie jest zgodne ze specyfikacją, nawet jeśli nie jest to zgodne z oczekiwaniami. Jeśli nie określisz zasady uruchamiania, przyjmuje się, że jest to async|deferred, co oznacza, że ​​decyzja należy do implementacji. GCC zdarza się zawsze wybierać deferred, jeśli masz wybór.

+0

Dzięki za wyczyszczenie tego. Myślałem, że wszystkie obecne implementacje są nieco "bardziej inteligentne", a nie tylko robią proste _deferred_. – Bouncner

+4

Proszę się nie zgodzić. Oto, co mówi norma (podkreślenie moje): "Jeśli ta zasada jest określona razem z innymi zasadami, na przykład gdy używana jest wartość policy' launch :: async | launch :: deferred ", implementacje powinny odroczyć wywołanie lub wybór zasadę, kiedy nie można efektywniej wykorzystać współbieżności. " Różni się to znacznie od uruchamiania nowego wątku odroczonego. –

5

EDIT2: wytłumaczę nieco więcej.

std :: async obiecuje "przyszłość"; to znaczy: kiedy tego chcesz, będzie tam. Można to teraz obliczyć, może zostać obliczone, gdy o to poprosisz, po prostu obiecujemy, że to się stanie.

Podobnie jak w przypadku plakatu znajdującego się poniżej, GCC domyślnie odracza (co oznacza, że ​​spełni tę obietnicę, gdy zostanie o to poproszony, a prawdopodobnie wcześniej). Powodem tego domyślnego jest to, że GCC nie zapewnia jeszcze odpowiedniej obsługi wątków w C++ 11. Nie ma dobrego programu do planowania wątków wewnętrznych i wielu innych rzeczy. To trochę hack. Nie, bardziej jak banda hakerów. W rzeczywistości, jeśli napiszesz kod wątku w C++ 11 na GCC, to jest tak, że gdy wykonają funkcje, będzie działać poprawnie; teraz to w większości działa poprawnie. Mam na myśli, że dostajesz wynik w końcu, prawda?

Jeśli powiesz mu, aby uruchomić wątek, będzie, ponieważ jest zbyt głupi (w tej chwili), aby zdać sobie sprawę, że może i powinien na własną rękę (w przeciwieństwie do CLang, który ma obecnie lepszy wewnętrzny program planujący wątek).

EDYCJA: Poważnie? Nieprawidłowe modmowanie w dół!

Oto moje referencje! http://gcc.gnu.org/projects/cxx0x.html. Zauważ, że prawie wszystko pod "współbieżnością", w tym "model pamięci", jest oznaczone jako NIE. GCC.GNU.org. Są autorytetem w GCC, który znasz.

Lekko edytowane z moim komentarzem:

naprawdę polecam przy użyciu doładowania. To nie będzie duży skok do właściwej obsługi C++ 11, gdy GCC jest gotowy. Nowe modele wątków w C++ 11 wymagają innego układu pamięci, niż używają GCC lub MSVC i nie są jeszcze zaimplementowane.

+3

Co zmieniło się w C++ 11 pod względem "układu pamięci"? –

+0

@NicolBolas http://gcc.gnu.org/projects/cxx0x.html. Zauważ, że prawie wszystko pod "współbieżnością", w tym "model pamięci", jest oznaczone jako NIE –

+5

Tak, ale to nie wyjaśnia, co zmieniło się w "układzie pamięci *". Układ dotyczy tego, gdzie rzeczy mają się w związku z innymi rzeczami. Model * pamięci * wyjaśnia reguły dotyczące tego, kiedy zmienne dostępu stają się widoczne w innych wątkach i tym podobnych. –

1

Rozumiem, że jest to 2 lata później, ale nie mogę oprzeć się wrażeniu, że muszę odpowiedzieć na komentarz @ std''rggnDave o GCC vs. CLang, aby zauważyć, że przynajmniej obecnie, styczeń 2015, zarówno Wersja CLANG 3.5 i GCC w wersji 4.9 mają dokładnie to samo zachowanie.Takie zachowanie polega na tym, że jeśli nie podano żadnych zasad uruchamiania, domyślnie różnicuje się i wykonuje, gdy wywoływana jest funkcja future :: get, i tylko wtedy, gdy jawnie podano zasady uruchamiania asynchronicznego, albo kompilator prowadzi do wykonywania funkcji w tle.

Powiązane problemy