2013-02-13 3 views
13

Próbuję przyspieszyć program przy użyciu std :: async. Załóżmy, że mam funkcję, która jest droga do skopiowania, gdzie T jest typem kosztownym. Mam kilka niezależnych wywołań f z różnymi argumentami i staram się je zrównoleglić ze std :: async mniej więcej tak: (gdzie m_futures jest std :: vector futures właściwego typu).Dlaczego std :: async kopiuje jego const & arguments?

for (...) { 
    m_futures.push_back (
     std::async(
      std::launch::async, 
      f, 
      a,b,c)); 
} 

Zaobserwowałem, że powyższy kod spowalnia wykonywanie mojego programu. Przeszedłem przez to z gdb i kiedy tworzona jest przyszłość, konstruktor kopii T jest wywoływany trzy razy. Dlaczego? Argumenty a, b, c są przydzielane sterty, ale może kompilator o tym nie wie? Czy mogę to jakoś wyrazić?

Czy zawsze jest tak, że std :: async tworzy kopie argumentów, nawet jeśli powinny być przekazywane przez odniesienie do const? Czy mogę tego w jakiś sposób uniknąć? W moim naiwnym umyśle powinien być po prostu wskaźnik przekazany do różnych wywołań funkcji (która tak czy inaczej odczytuje z pamięci). Używam gcc-4.6.3 na Linuksie, jeśli to ma znaczenie.

Odpowiedz

19

Zapisywanie referencji nie byłoby bezpieczne, ponieważ nie ma niczego, co zagwarantowałoby brak wyścigów danych (a co ważniejsze, samo istnienie obiektu istnienie obiektów, jak powiedziała @utapistim w swoim smutnie usuniętym wpisie).

Jeśli rzeczywiście chcesz odniesienie zamiast kopii i ty „re skłonny postawić swoje życie na co jest prawidłowe, a następnie można po prostu wykorzystać owijki odniesienia:

std::async(std::launch::async, f, std::cref(a), std::cref(b), std::cref(c)) 
+1

Z ciekawości co się stanie, jeśli zmienię interfejs i jawnie przekazuję wskaźnik? Czy to by było równoznaczne z używaniem opakowań referencyjnych? – Thomas

+0

@Thomas: Tak. Opakowania referencyjne * są * w zasadzie wskaźnikami. Nie używaj gołych wskaźników w C++ (z wyjątkiem prywatnych członków klasy). Wolisz opakowania referencyjne. –

+0

OK, dzięki, nie wiedziałem o opakowaniu referencyjnym. – Thomas