หลังจากที่กำลังมองหาที่พวง ของ อื่น ๆ คำถาม และ พวกเขา ตอบฉันได้รับความประทับใจที่ไม่มีข้อตกลงอย่างกว้างขวางในสิ่งที่ "ผันผวน" คำหลักใน C หมายความว่า
แม้มาตรฐานของตัวเองดูเหมือนจะไม่เพียงพอที่ชัดเจนสำหรับทุกคนที่จะเห็นด้วยกับสิ่งที่มันหมายถึง
ท่ามกลางปัญหาอื่น ๆ :
- ดูเหมือนว่าจะให้การรับประกันที่แตกต่างกันขึ้นอยู่กับฮาร์ดแวร์ของคุณและขึ้นอยู่กับคอมไพเลอร์ของคุณ
- มันมีผลต่อการปรับให้เหมาะสมของคอมไพเลอร์ แต่ไม่ใช่การปรับให้เหมาะสมของฮาร์ดแวร์ดังนั้นในโปรเซสเซอร์ขั้นสูงที่ทำการปรับแต่งให้เหมาะสมนั้นไม่ชัดเจนว่าคอมไพเลอร์สามารถป้องกันการปรับให้เหมาะสมที่คุณต้องการป้องกันได้หรือไม่ (คอมไพเลอร์บางตัวสร้างคำแนะนำเพื่อป้องกันการปรับแต่งฮาร์ดแวร์บางอย่างในบางระบบ แต่สิ่งนี้ดูเหมือนจะไม่ได้มาตรฐานในทางใดทางหนึ่ง)
เพื่อสรุปปัญหาปรากฏขึ้น (หลังจากอ่านมาก) ว่า "volatile" รับประกันสิ่งที่ต้องการ: ค่าจะอ่าน / เขียนไม่เพียงจาก / ไปยังการลงทะเบียน แต่อย่างน้อยกับแคช L1 หลักในลำดับเดียวกันกับที่ การอ่าน / เขียนจะปรากฏขึ้นในรหัส แต่สิ่งนี้ดูไร้ประโยชน์เนื่องจากการอ่าน / เขียนจาก / ไปยังการลงทะเบียนนั้นเพียงพอแล้วในเธรดเดียวกันในขณะที่การประสานงานกับแคช L1 ไม่รับประกันอะไรเพิ่มเติมเกี่ยวกับการประสานงานกับเธรดอื่น ๆ ฉันนึกภาพไม่ออกเลยว่ามันจะสำคัญเมื่อต้องซิงค์เพียงกับแคช L1
ใช้ 1 การใช้
งานเพียงอย่างเดียวที่ยอมรับได้อย่างกว้างขวางสำหรับระบบเก่าหรือระบบฝังตัวที่ตำแหน่งหน่วยความจำบางตำแหน่งถูกแมปฮาร์ดแวร์กับฟังก์ชั่น I / O เช่นหน่วยความจำเล็กน้อยที่ควบคุม (ในฮาร์ดแวร์โดยตรง) แสง หรือหน่วยความจำเล็ก ๆ น้อย ๆ ที่บอกคุณว่าแป้นคีย์บอร์ดหยุดทำงานหรือไม่ (เพราะฮาร์ดแวร์เชื่อมต่อโดยตรงกับกุญแจ)
ดูเหมือนว่า"ใช้ 1" ไม่เกิดขึ้นในรหัสพกพาที่มีเป้าหมายรวมถึงระบบมัลติคอร์
ใช้ 2
ไม่แตกต่างจาก "ใช้ 1" คือหน่วยความจำที่สามารถอ่านหรือเขียนได้ตลอดเวลาโดยตัวจัดการขัดจังหวะ (ซึ่งอาจควบคุมแสงหรือข้อมูลการจัดเก็บจากคีย์) แต่สำหรับตอนนี้เรามีปัญหาที่ขึ้นอยู่กับระบบตัวจัดการขัดจังหวะอาจทำงานบน แกนที่แตกต่างกับหน่วยความจำแคชของตัวเองและ "ระเหย" ไม่รับประกันความสอดคล้องกันแคชในทุกระบบ
ดังนั้น"ใช้ 2" ดูเหมือนจะเกินกว่าที่ "ระเหย" สามารถส่งมอบได้
ใช้ 3
การใช้ที่ไม่มีข้อโต้แย้งเพียงอย่างเดียวที่ฉันเห็นคือการป้องกันการปรับการเข้าถึงผิดพลาดผ่านตัวแปรต่างๆที่ชี้ไปยังหน่วยความจำเดียวกันที่คอมไพเลอร์ไม่ได้ตระหนักถึงคือหน่วยความจำเดียวกัน แต่สิ่งนี้อาจไม่มีข้อโต้แย้งเพียงเพราะคนไม่ได้พูดถึงมัน - ฉันเห็นเพียงหนึ่งกล่าวถึง และฉันคิดว่ามาตรฐาน C รู้อยู่แล้วว่าพอยน์เตอร์ "แตกต่าง" (เช่น args ที่แตกต่างกันไปยังฟังก์ชั่น) อาจชี้ไปที่รายการเดียวกันหรือรายการใกล้เคียงและระบุไว้แล้วว่าคอมไพเลอร์จะต้องสร้างรหัส อย่างไรก็ตามฉันไม่พบหัวข้อนี้อย่างรวดเร็วในมาตรฐาน (500 หน้า!)
ดังนั้น"ใช้ 3" อาจไม่มีอยู่เลย?
ดังนั้นคำถามของฉัน:
"volatile" รับประกันอะไรในรหัส C แบบพกพาสำหรับระบบมัลติคอร์หรือไม่?
แก้ไข - อัปเดต
หลังจากเรียกดูมาตรฐานล่าสุดก็จะมองเช่นคำตอบคืออย่างน้อยมากจำกัด ใช่:
1. มาตรฐานซ้ำ ๆ ระบุการรักษาพิเศษสำหรับประเภทที่เฉพาะเจาะจง "sig_atomic_t ผันผวน" อย่างไรก็ตามมาตรฐานยังบอกว่าการใช้ฟังก์ชั่นสัญญาณในโปรแกรมแบบมัลติเธรดส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด ดังนั้นกรณีใช้งานนี้ดูเหมือนจะ จำกัด การสื่อสารระหว่างโปรแกรมแบบเธรดเดียวและตัวจัดการสัญญาณ
2. มาตรฐานยังระบุความหมายที่ชัดเจนสำหรับ "volatile" ที่สัมพันธ์กับ setjmp / longjmp (ตัวอย่างรหัสที่ให้ไว้ในคำถามและคำตอบอื่น ๆ)
ดังนั้นคำถามที่แม่นยำยิ่งขึ้นจะกลายเป็น:
"ระเหย" รับประกันอะไรในรหัส C แบบพกพาสำหรับระบบมัลติคอร์นอกเหนือจาก (1) อนุญาตให้โปรแกรมแบบเธรดเดียวรับข้อมูลจากตัวจัดการสัญญาณหรือ (2) อนุญาตให้ setjmp รหัสเพื่อดูตัวแปรแก้ไขระหว่าง setjmp และ longjmp?
นี่ยังเป็นคำถามใช่ / ไม่ใช่
หาก "ใช่" จะเป็นการดีถ้าคุณสามารถแสดงตัวอย่างของรหัสแบบพกพาที่ไม่มีบั๊กซึ่งกลายเป็นข้อผิดพลาดหากละเว้น "volatile" หาก "ไม่" ฉันคิดว่าคอมไพเลอร์มีอิสระที่จะเพิกเฉยต่อ "ความผันผวน" นอกสองกรณีนี้โดยเฉพาะสำหรับเป้าหมายแบบมัลติคอร์
volatile
โดยเฉพาะซึ่งฉันเชื่อว่าจำเป็น
volatile
แจ้งโปรแกรมว่าอาจเปลี่ยนแปลงแบบอะซิงโครนัส