Odkryłem, że kompilator Intel nie generuje optymalizacji wartości zwracanej dla obiektów std :: array. Poniższy kod, który znajduje się w wewnętrznej pętli mojego programu, nie jest zoptymalizowany, tak jak mógł.Czy Optymalizacja wartości zwracanej musi zadeklarować konstruktora kopiowania
std::array<double, 45> f(const std::array<double, 45>& y) {
auto dy_dt = std::array<double, 45>();
...
return dy_dt;
}
I zorientowali się, że takie zachowanie wynika z faktu, że moja średnia realizacja biblioteka nie jawnie zdefiniować konstruktor kopiujący dla std :: tablicy. Poniższy kod demonstruje, że:
class Test {
public:
Test() = default;
Test(const Test& x);
};
Test f() {
auto x = Test();
return x;
}
Podczas kompilowania go
icpc -c -std=c++11 -qopt-report=2 test.cpp -o test.o
plik raport pokazuje
INLINE REPORT: (f(Test *)) [1] main.cpp(7,10)
co dowodzi, że kompilator generuje RVO (podpis f ulega zmianie dzięki czemu może umieścić nowo utworzony obiekt na stosie strony wywołującej). Ale jeśli wykomentuj wiersz deklaruje Test(const Test& x);
plik raport pokazuje
INLINE REPORT: (f()) [1] main.cpp(7,10)
co dowodzi, że RVO nie jest generowany.
W 12.8.31 standardu C++ 11, który definiuje RVO, przykład, który podają, ma konstruktora kopii. Czy jest to "błąd" kompilatora Intela lub zgodna implementacja standardu?
@Cyber Nie, gdyby RVO było możliwe, to usunąłoby kopię. – juanchopanza
Cyber: Nie, ta funkcja nazywa się optymalizacją wartości zwracanej. Nie ma nic wspólnego z semantyką ruchu. – InsideLoop
RVO nie potrzebuje konstruktora kopiowania jako takiego, ale kod, którego dotyczyłaby aplikacja RVO, musi mieć dostępny poprawny konstruktor kopii lub przeniesienia. – juanchopanza