Setelah melihat sekelompok dari lainnya pertanyaan dan mereka jawaban , saya mendapatkan kesan bahwa tidak ada kesepakatan luas tentang apa yang "volatile" kata kunci dalam C berarti persis.
Bahkan standar itu sendiri tampaknya tidak cukup jelas bagi semua orang untuk menyetujui apa artinya .
Di antara masalah lain:
- Tampaknya memberikan jaminan yang berbeda tergantung pada perangkat keras Anda dan tergantung pada kompiler Anda.
- Ini mempengaruhi pengoptimalan kompiler tetapi bukan pengoptimalan perangkat keras, jadi pada prosesor tingkat lanjut yang melakukan pengoptimalan run-time sendiri, bahkan tidak jelas apakah kompiler dapat mencegah pengoptimalan apa pun yang ingin Anda cegah. (Beberapa kompiler memang menghasilkan instruksi untuk mencegah beberapa optimasi perangkat keras pada beberapa sistem, tetapi ini tampaknya tidak distandarisasi dengan cara apa pun.)
Untuk meringkas masalah, tampak (setelah membaca banyak) bahwa "volatile" menjamin sesuatu seperti: Nilai akan dibaca / ditulis tidak hanya dari / ke register, tetapi setidaknya ke cache L1 inti, dalam urutan yang sama yang baca / tulis muncul dalam kode. Tapi ini tampaknya tidak berguna, karena membaca / menulis dari / ke register sudah cukup dalam utas yang sama, sementara berkoordinasi dengan L1 cache tidak menjamin apa pun lebih lanjut mengenai koordinasi dengan utas lainnya. Saya tidak bisa membayangkan kapan bisa penting untuk melakukan sinkronisasi hanya dengan cache L1.
PENGGUNAAN 1.
Satu-satunya penggunaan volatile yang disepakati secara luas tampaknya untuk sistem lama atau tertanam di mana lokasi memori tertentu dipetakan perangkat keras ke fungsi I / O, seperti sedikit dalam memori yang mengontrol (langsung, dalam perangkat keras) lampu. , atau sedikit dalam memori yang memberi tahu Anda apakah tombol keyboard turun atau tidak (karena terhubung oleh perangkat keras langsung ke tombol).
Tampaknya "gunakan 1" tidak terjadi dalam kode portabel yang targetnya mencakup sistem multi-core.
PENGGUNAAN 2
Tidak jauh berbeda dari "penggunaan 1" adalah memori yang dapat dibaca atau ditulis kapan saja oleh penangan interupsi (yang mungkin mengontrol lampu atau menyimpan info dari kunci). Tetapi sudah untuk ini kita memiliki masalah yang tergantung pada sistem, penangan interrupt mungkin berjalan pada inti yang berbeda dengan cache memori sendiri , dan "volatile" tidak menjamin koherensi cache pada semua sistem.
Jadi "use 2" tampaknya melampaui apa yang "volatile" dapat berikan.
GUNAKAN 3
Satu-satunya penggunaan tak terbantahkan lainnya yang saya lihat adalah untuk mencegah kesalahan optimasi akses melalui variabel yang berbeda yang menunjuk ke memori yang sama yang tidak disadari oleh kompiler adalah memori yang sama. Tetapi ini mungkin hanya tidak perlu dipermasalahkan karena orang tidak membicarakannya - saya hanya melihat satu menyebutkannya. Dan saya pikir standar C sudah mengakui bahwa pointer "berbeda" (seperti argumen yang berbeda untuk suatu fungsi) mungkin menunjuk ke item yang sama atau item terdekat, dan sudah menentukan bahwa kompiler harus menghasilkan kode yang berfungsi bahkan dalam kasus seperti itu. Namun, saya tidak dapat dengan cepat menemukan topik ini dalam standar (500 halaman!) Terbaru.
Jadi "gunakan 3" mungkin tidak ada sama sekali?
Karena itu pertanyaan saya:
Apakah "volatile" menjamin semuanya dalam kode C portabel untuk sistem multi-core?
EDIT - perbarui
Setelah browsing standar terbaru , sepertinya jawabannya paling tidak ya sangat terbatas:
1. Standar berulang kali menentukan perlakuan khusus untuk tipe spesifik "volatile sig_atomic_t". Namun standar juga mengatakan bahwa penggunaan fungsi sinyal dalam program multi-threaded menghasilkan perilaku yang tidak terdefinisi. Jadi use case ini tampaknya terbatas pada komunikasi antara program single-threaded dan pengendali sinyal.
2. Standar juga menentukan arti yang jelas untuk "volatile" dalam kaitannya dengan setjmp / longjmp. (Kode contoh yang penting diberikan dalam pertanyaan dan jawaban lain .)
Jadi pertanyaan yang lebih tepat adalah:
Apakah "volatile" menjamin semuanya dalam kode C portabel untuk sistem multi-inti, selain dari (1) memungkinkan program berulir tunggal untuk menerima informasi dari pengendali sinyal, atau (2) memungkinkan setjmp kode untuk melihat variabel yang dimodifikasi antara setjmp dan longjmp?
Ini masih merupakan pertanyaan ya / tidak.
Jika "ya", alangkah baiknya jika Anda dapat menunjukkan contoh kode portabel bebas bug yang menjadi bermasalah jika "tidak stabil" dihilangkan. Jika "tidak", maka saya kira kompiler bebas untuk mengabaikan "volatile" di luar dua kasus yang sangat spesifik ini, untuk target multi-core.
volatile
spesifik, yang saya percaya perlu.
volatile
menginformasikan program bahwa itu dapat berubah secara tidak sinkron.