7

キャッシュ境界で型をオーバーアラインしたいので、次を使用しましたalignas

struct alignas(64) W { };

これはうまくコンパイルされます。しかし、驚いたことに、一連の s を割り当てようとするとW、それらは 64 バイトでアラインされていませんが、実際には 16 バイトでアラインされています。

#include <iostream>
#include <iomanip>
#include <unordered_map>

struct alignas(64) W { };

int main() {
    std::unordered_map<int, int> offset;

    for (int i = 0; i < 1000; ++i) {
        auto w = new W;
        offset[(uintptr_t)w % 64]++;
    }   

    for (const auto& p : offset) {
        std::cout << p.first << ' ' << p.second << '\n';
    }   
}

収量:

0 250
16 250
32 250
48 250

いくつかのコンパイル (gcc 4.8.2、gcc 5.2.0、clang 3.7.1) で。調子はどう?整列するように言ったのに、なぜ整列しないのですか?

4

2 に答える 2

2

他の答えは、既存の制限を説明するという意味では正しいですが、状況は改善されようとしていることを指摘したいと思います。

コメントで TC が示したように、これは言語の長年にわたる欠陥でした。これを修正するための WG の取り組みにより、C++17 での解決につながったようです (これは、機能が完全状態になったばかりです)。したがって、その標準にコンパイルすると、オーバーアラインメントは動的割り当てによって最終的に尊重され、新しいオーバーロードが使用されます。したがって、バリーの問題を解決します!std::align_val_tnew

必要な新しい足場の量を考えると、これが標準の以前のバージョンにバックポートされることはないと思います。そのため、基本的なアライメントを持つ型に対してのみ十分な動的割り当てに関する古い警告は、おそらくそのままです。

于 2016-06-30T21:26:08.230 に答える