Pertanyaan Bagaimana cara kompiler C ++ mendukung atom C ++ 11, tetapi tidak mendukung model memori C ++ 11


Sambil melihat status penerapan Clang dan g ++ C ++ 11 saya melihat ada yang aneh:
mereka mendukung atom C ++ 11, tetapi mereka tidak mendukung model memori C ++ 11.
Saya mendapat kesan bahwa Anda harus memiliki model memori C ++ 11 untuk menggunakan atom. Jadi apa sebenarnya perbedaan antara dukungan untuk atom dan model memori?
Apakah kurangnya dukungan model memori berarti program C ++ 11 legal yang digunakan std::atomic<T> arent seq konsisten?

referensi:
http://clang.llvm.org/cxx_status.html
http://gcc.gnu.org/gcc-4.7/cxx0x_status.html


32
2017-07-02 12:40


asal


Jawaban:


Salah satu masalah adalah definisi "lokasi memori", yang memungkinkan (dan memaksa kompiler untuk mendukung) mengunci anggota struktur yang berbeda dengan kunci yang berbeda. Ada sebuah diskusi tentang masalah RL yang disebabkan oleh ini.

Pada dasarnya masalahnya adalah bahwa memiliki struct didefinisikan seperti ini:

struct x {
    long a;
    unsigned int b1;
    unsigned int b2:1;
};

compiler bebas untuk menerapkan penulisan kepada b2 dengan menimpanya b1 juga (dan ternyata, kalau dilihat dari laporan, memang demikian). Oleh karena itu, kedua bidang harus dikunci sebagai satu. Namun, sebagai konsekuensi dari model memori C ++ 11, ini terlarang (baik, tidak benar-benar dilarang, tetapi compiler harus memastikan pembaruan simultan ke b1 dan b2 Jangan ikut campur; itu bisa dilakukan dengan mengunci atau CAS-ing setiap pembaruan tersebut, baik, hidup sulit pada beberapa arsitektur). Mengutip dari laporan:

Saya telah mengangkat masalah dengan orang-orang GCC kami dan mereka berkata kepada saya bahwa: "C   tidak memberikan jaminan seperti itu, Anda juga tidak dapat mengunci kunci yang berbeda   bidang struktur dengan kunci berbeda jika mereka berbagi secara alami selaras   daerah memori ukuran kata. Model memori C ++ 11 akan menjamin ini,   tetapi itu tidak diimplementasikan atau Anda tidak membangun kernel dengan C ++ 11   penyusun."

Info bagus juga dapat ditemukan di wiki.


15
2017-07-06 09:43



Saya kira "Kekurangan model memori" dalam kasus ini hanya berarti bahwa pengoptimal ditulis sebelum model memori C ++ 11 dipublikasikan, dan mungkin melakukan pengoptimalan yang tidak valid. Ini sangat sulit dan memakan waktu untuk memvalidasi pengoptimalan terhadap model memori, jadi tidak mengherankan bahwa tim clang / gcc belum menyelesaikannya.

Apakah kurangnya dukungan model memori berarti bahwa program C ++ 11 legal yang menggunakan std :: atom arent seq konsisten?

Ya, itu kemungkinan. Ini bahkan lebih buruk: kompiler mungkin memperkenalkan ras data ke dalam (sesuai dengan standar C ++ 11 standar) program bebas balap, mis. dengan memperkenalkan tulisan spekulatif.

Sebagai contoh, beberapa kompiler C ++ digunakan untuk melakukan optimasi ini:

for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++count;
}

Bisa dioptimalkan menjadi:

register int r1 = count;
for (p = q; p = p -> next; ++p) {
    if (p -> data > 0) ++r1;
}
count = r1;

Aku jatuh p->data tidak negatif, kode sumber asli tidak ditulis count, tetapi kode yang dioptimalkan tidak. Ini dapat memperkenalkan balapan data dalam program yang bebas ras, sehingga spesifikasi C ++ 11 melarang pengoptimalan semacam itu. Kompiler yang ada sekarang harus memverifikasi (dan menyesuaikan jika perlu) semua pengoptimalan.

Lihat Concurrency konsekuensi kompilator model memori untuk detailnya.


11
2017-07-03 17:12



Ini tidak begitu banyak sehingga mereka tidak mendukung model memori, tetapi mereka tidak (belum) mendukung API dalam Standar untuk berinteraksi dengan model memori. API itu mencakup sejumlah muteks.

Namun, Clang dan GCC sama-sama sadar akan benang tanpa standar formal untuk beberapa waktu. Anda tidak perlu khawatir tentang pengoptimalan memindahkan hal-hal ke sisi yang salah dari operasi atom.


0
2017-07-02 18:55