次のような非常に単純な配列を作成する場合
int myArray[3] = {1,2,3};
代わりにstd::array
を使用する必要がありますか?
std::array<int, 3> a = {{1, 2, 3}};
通常のものよりもstd :: arrayを使用する利点は何ですか?より高性能ですか?コピー/アクセスの取り扱いが簡単ですか?
std::array
を通常のものよりも使用する利点は何ですか?
わかりやすい値のセマンティクスを備えているため、値によって関数とやり取りすることができます。そのインターフェイスにより、サイズを見つけやすくなり、STLスタイルの反復子ベースのアルゴリズムで使用しやすくなります。
より高性能ですか?
まったく同じでなければなりません。定義では、それは唯一のメンバーとして配列を含む単純な集合体です。
コピー/アクセスの取り扱いが簡単ですか?
はい。
std::array
は、Cスタイルの配列を囲む非常に薄いラッパーで、基本的に次のように定義されます。
template<typename T, size_t N>
class array
{
public:
T _data[N];
T& operator[](size_t);
const T& operator[](size_t) const;
// other member functions and typedefs
};
これは 集合 であり、基本型のように使用できます(つまり、値渡し、割り当てなどができますが、標準のC配列は別の配列に直接割り当てたりコピーしたりすることはできません。アレイ)。いくつかの標準的な実装(お気に入りのIDEまたは直接開く<array>
)、これは非常に読みやすく理解しやすいC++標準ライブラリの一部です。
std::array
は、他のC++コンテナのセマンティクスのような「通常の」値を与えるC配列のゼロオーバーヘッドラッパーとして設計されています。
追加の機能を引き続き利用しながら、実行時のパフォーマンスの違いに気付かないでください。
std::array
スタイルの配列の代わりにint[]
を使用することは、C++ 11またはboostを手元に持っている場合には良いアイデアです。
std::array
には値のセマンティクスがありますが、生の配列にはありません。つまり、std::array
をコピーして、プリミティブ値のように扱うことができます。関数引数として値または参照によってそれらを受け取り、値によってそれらを返すことができます。
std::array
を決してコピーしない場合、生の配列とパフォーマンスの違いはありません。コピーを作成する必要がある場合、std::array
は正しいことを行いますが、それでも同等のパフォーマンスが得られます。
より高性能ですか?
まったく同じでなければなりません。定義では、それは唯一のメンバーとして配列を含む単純な集合体です。
特定のプラットフォームによっては、std :: arrayがC-arrayと比較して常に同じアセンブリコードを生成するとは限らないため、状況はより複雑に思われます。
Godbolt.orgでこの特定の状況をテストしました。
#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++) {
//double arr[2] = {0.e0};//
std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
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とClangは、C-arrayバージョンとstd :: arrayバージョンの両方で同一のアセンブリコードを生成します。
ただし、MSVCとICPCは、アレイのバージョンごとに異なるアセンブリコードを生成します。 (ICPC19を-Ofastおよび-Os、MSVC -Oxおよび-Osでテストしました)
なぜそうなのか、私にはわからない(std :: arrayとc-arrayのまったく同じ振る舞いを期待するだろう)。おそらく、さまざまな最適化戦略が採用されています。
少し余分に:icpcにバグがあるようです
#pragma simd
いくつかの状況でc-arrayを使用する場合のベクトル化(c-arrayコードは誤った出力を生成します。std:: arrayバージョンは正常に動作します)。残念ながら、非常に複雑なコードの最適化中にその問題を発見したため、まだ実用的な最小限の例はありません。 c_array/std :: arrayと#pragma simdについて何かを誤解しただけではないと確信したら、インテルにバグ報告を提出します。