Czy jest bardziej wydajny?
Powinien być dokładnie taki sam. Z definicji jest to prosta agregacja zawierająca tablicę jako jedyny element członkowski.
Sytuacja wydaje się być bardziej skomplikowana, ponieważ std::array
nie zawsze tworzy identyczny kod asemblera w porównaniu z tablicą C, w zależności od konkretnej platformy.
Przetestowałem tę konkretną sytuację na godbolt :
#include <array>
void test(double* const C, const double* const A,
const double* const B, const size_t size) {
for (size_t i = 0; i < size; i++) {
std::array<double, 2> arr = {0.e0};
for (size_t j = 0; j < size; j++) {
arr[0] += A[i] * B[j];
arr[1] += A[j] * B[i];
}
C[i] += arr[0];
C[i] += arr[1];
}
}
GCC i Clang generują identyczny kod asemblera zarówno dla wersji C-array, jak i dla std::array
wersji.
Jednak MSVC i ICPC generują inny kod asemblera dla każdej wersji macierzy. (Testowałem ICPC19 z -Ofast
i -Os
; MSVC -Ox
i-Os
)
Nie mam pojęcia, dlaczego tak jest (rzeczywiście spodziewałbym się dokładnie identycznego zachowania std :: array i c-array). Może są stosowane różne strategie optymalizacji.
Jako mały dodatek: wygląda na to, że w ICPC jest błąd z
#pragma simd
do wektoryzacji podczas używania tablicy c w niektórych sytuacjach (kod c-array generuje nieprawidłowe dane wyjściowe; std::array
wersja działa dobrze).
Niestety nie mam jeszcze minimalnego przykładu roboczego na to, ponieważ odkryłem ten problem podczas optymalizacji dość skomplikowanego fragmentu kodu.
Prześlę raport o błędzie do firmy Intel, gdy będę pewien, że nie tylko źle zrozumiałem coś o C-array / std::array
i #pragma simd
.