Sau khi xem xét một loạt các khác câu hỏi và họ trả lời , tôi nhận được ấn tượng rằng không có thoả thuận rộng rãi về những gì từ khóa "không ổn định" trong C có nghĩa là chính xác.
Ngay cả bản thân tiêu chuẩn dường như cũng không đủ rõ ràng để mọi người đồng ý về ý nghĩa của nó .
Trong số các vấn đề khác:
- Nó dường như cung cấp các đảm bảo khác nhau tùy thuộc vào phần cứng của bạn và tùy thuộc vào trình biên dịch của bạn.
- Nó ảnh hưởng đến tối ưu hóa trình biên dịch nhưng không tối ưu hóa phần cứng, do đó, trên bộ xử lý tiên tiến thực hiện tối ưu hóa thời gian chạy của chính nó, thậm chí không rõ liệu trình biên dịch có thể ngăn chặn bất kỳ tối ưu hóa nào bạn muốn ngăn chặn hay không. (Một số trình biên dịch tạo ra các hướng dẫn để ngăn chặn một số tối ưu hóa phần cứng trên một số hệ thống, nhưng điều này dường như không được tiêu chuẩn hóa theo bất kỳ cách nào.)
Để tóm tắt vấn đề, có vẻ như (sau khi đọc rất nhiều) rằng "dễ bay hơi" đảm bảo một cái gì đó như: Giá trị sẽ được đọc / ghi không chỉ từ / đến một thanh ghi, mà ít nhất là vào bộ đệm L1 của lõi, theo cùng thứ tự việc đọc / ghi xuất hiện trong mã. Nhưng điều này có vẻ vô dụng, vì đọc / ghi từ / đến một thanh ghi đã đủ trong cùng một luồng, trong khi phối hợp với bộ đệm L1 không đảm bảo bất cứ điều gì thêm về việc phối hợp với các luồng khác. Tôi không thể tưởng tượng khi nào việc đồng bộ hóa chỉ với bộ đệm L1 có thể rất quan trọng.
SỬ DỤNG 1
Việc sử dụng dễ bay hơi được chấp thuận rộng rãi dường như chỉ dành cho các hệ thống cũ hoặc nhúng trong đó các vị trí bộ nhớ nhất định được ánh xạ phần cứng tới các chức năng I / O, giống như một chút trong bộ nhớ điều khiển (trực tiếp, trong phần cứng) một ánh sáng hoặc một chút trong bộ nhớ cho bạn biết liệu phím bàn phím có bị hỏng hay không (bởi vì nó được kết nối trực tiếp bởi phần cứng với phím).
Có vẻ như "sử dụng 1" không xảy ra trong mã di động có mục tiêu bao gồm các hệ thống đa lõi.
SỬ DỤNG 2
Không quá khác biệt so với "sử dụng 1" là bộ nhớ có thể được đọc hoặc ghi bất cứ lúc nào bởi một trình xử lý ngắt (có thể điều khiển ánh sáng hoặc lưu trữ thông tin từ một phím). Nhưng đối với điều này, chúng ta có một vấn đề là tùy thuộc vào hệ thống, trình xử lý ngắt có thể chạy trên một lõi khác với bộ nhớ cache riêng và "không ổn định" không đảm bảo tính liên kết của bộ đệm trên tất cả các hệ thống.
Vì vậy, "sử dụng 2" dường như vượt quá những gì "dễ bay hơi" có thể mang lại.
SỬ DỤNG 3
Cách sử dụng không thể tranh cãi khác mà tôi thấy là để ngăn chặn tối ưu hóa truy cập sai thông qua các biến khác nhau chỉ vào cùng một bộ nhớ mà trình biên dịch không nhận ra là cùng một bộ nhớ. Nhưng điều này có lẽ chỉ là không thể tranh cãi bởi vì mọi người không nói về nó - tôi chỉ thấy một đề cập đến nó. Và tôi nghĩ rằng tiêu chuẩn C đã nhận ra rằng các con trỏ "khác nhau" (như các đối số khác nhau của một hàm) có thể trỏ đến cùng một mục hoặc các mục gần đó và đã chỉ định rằng trình biên dịch phải tạo mã hoạt động ngay cả trong các trường hợp như vậy. Tuy nhiên, tôi không thể nhanh chóng tìm thấy chủ đề này trong tiêu chuẩn mới nhất (500 trang!).
Vì vậy, "sử dụng 3" có thể không tồn tại?
Do đó câu hỏi của tôi:
"Biến động" có đảm bảo bất cứ điều gì trong mã C di động cho các hệ thống đa lõi không?
EDIT - cập nhật
Sau khi duyệt tiêu chuẩn mới nhất , có vẻ như câu trả lời ít nhất là rất hạn chế:
1. Tiêu chuẩn liên tục chỉ định điều trị đặc biệt cho loại cụ thể "dễ bay hơi sig_atomic_t". Tuy nhiên, tiêu chuẩn cũng nói rằng việc sử dụng chức năng tín hiệu trong chương trình đa luồng dẫn đến hành vi không xác định. Vì vậy, trường hợp sử dụng này dường như bị giới hạn trong giao tiếp giữa một chương trình đơn luồng và trình xử lý tín hiệu của nó.
2. Tiêu chuẩn cũng chỉ định một ý nghĩa rõ ràng cho "dễ bay hơi" liên quan đến setjmp / longjmp. (Mã ví dụ về vấn đề được đưa ra trong các câu hỏi và câu trả lời khác .)
Vì vậy, câu hỏi chính xác hơn trở thành:
"Biến động" có đảm bảo bất cứ điều gì trong mã C di động cho các hệ thống đa lõi không, ngoài (1) cho phép một chương trình đơn luồng nhận thông tin từ trình xử lý tín hiệu của nó, hoặc (2) cho phép setjmp mã để xem các biến được sửa đổi giữa setjmp và longjmp?
Đây vẫn là một câu hỏi có / không.
Nếu "có", sẽ thật tuyệt nếu bạn có thể hiển thị một ví dụ về mã di động không có lỗi sẽ bị lỗi nếu "không ổn định" bị bỏ qua. Nếu "không", thì tôi cho rằng một trình biên dịch có thể bỏ qua "dễ bay hơi" bên ngoài hai trường hợp rất cụ thể này, cho các mục tiêu đa lõi.
volatile
cụ thể, mà tôi tin là cần thiết.
volatile
thông báo cho chương trình rằng nó có thể thay đổi không đồng bộ.