2014-07-03 9 views
7

Chcę zainicjować niektóre dane statyczne w wątku głównym.Czy funkcje mogą być zoptymalizowane, jeśli mają efekty uboczne?

int32_t GetFoo(ptime t) 
{ 
    static HugeBarData data; 
    return data.Baz(t); 
} 

int main() 
{ 
    GetFoo(); // Avoid data race on static field. 
       // But will it be optimized away as unnecessary? 

    // Spawn threads. Call 'GetFoo' on the threads. 
} 

Jeśli kompilator może zdecydować, aby go usunąć, jak mogę zmusić go tam pozostać?

+0

Jestem ostrożny z optymizmem, że osoby piszące kompilatory są wystarczająco inteligentne, aby nie wyrzucać wywołań funkcji, które mają skutki uboczne, tylko dlatego, że odrzucasz ich wartość zwrotu. – meagar

+0

Wolałbym docenić jakąś odpowiednią sekcję normy. – Sam

+1

Jeśli Twoim celem jest uniknięcie wyścigu (jak mówi komentarz kodu źródłowego), nie potrzebujesz pierwszego połączenia. C++ 11 gwarantuje brak warunków wyścigu dla lokalnej inicjalizacji zmiennych statycznych (poprzednie wersje standardu milczą na temat wątków). – Eugene

Odpowiedz

4

kompilatory muszą zoptymalizować zgodnie z zasadą "co-jeśli". Oznacza to, że po każdej optymalizacji program musi nadal zachowywać się (w sensie logicznym) tak, jakby kod nie był zoptymalizowany.

Jeśli występują efekty uboczne dla funkcji, każda optymalizacja musi zachować skutki uboczne. Jeśli jednak kompilator może stwierdzić, że wynik działań niepożądanych nie ma wpływu na resztę programu, może zoptymalizować nawet skutki uboczne. Kompilatory są bardzo konserwatywne w tym obszarze. Jeśli twój kompilator optymalizuje skutki uboczne konstruktora HugeBarData lub wywołania baz, które są wymagane w innym miejscu w programie, jest to błąd w kompilatorze.

Istnieje kilka wyjątków, w których kompilator może dokonywać optymalizacji, które zmieniają zachowanie programu z niezoptymalizowanego przypadku, zwykle obejmującego kopie. Nie sądzę, że ma tu zastosowanie którykolwiek z tych wyjątków.

Powiązane problemy