ในบทความที่มีชื่อเดียวกันกับคำถามนี้ผู้เขียนอธิบายถึงวิธีการสร้างการดำเนินการCAS แบบหลายคำที่ไม่บล็อก เชิงเส้น แบบปรับขนาดได้โดยใช้ CAS แบบคำเดียว พวกเขาแนะนำการดำเนินการแบบ double-compare-single-swap ครั้งแรก - RDCSS ดังนี้:
word_t RDCSS(RDCSSDescriptor_t *d) {
do {
r = CAS1(d->a2, d->o2, d);
if (IsDescriptor(r)) Complete(r);
} while (IsDescriptor(r));
if (r == d->o2) Complete(d); // !!
return r;
}
void Complete(RDCSSDescriptor_t *d) {
v = *(d->a1);
if (v == d->o1) CAS1(d->a2, d, d->n2);
else CAS1(d->a2, d, d->o2);
}
โดยที่RDCSSDescriptor_t
เป็นโครงสร้างที่มีฟิลด์ต่อไปนี้:
a1
- ที่อยู่ของเงื่อนไขแรกo1
- คาดหวังค่าที่อยู่แรกa2
- ที่อยู่ของเงื่อนไขที่สองo2
- คาดหวังค่าที่อยู่ที่สองn2
- ค่าใหม่ที่จะเขียนตามที่อยู่ที่สอง
descriptor นี้ถูกสร้างและเริ่มต้นครั้งเดียวในเธรดที่เริ่มต้นการดำเนินการ RDCSS - ไม่มีเธรดอื่นใดที่มีการอ้างอิงถึงจนกระทั่ง CAS1 แรกในฟังก์ชันRDCSS
สำเร็จ, ทำให้ descriptor สามารถเข้าถึงได้ (หรือใช้งานในคำศัพท์ของกระดาษ)
แนวคิดเบื้องหลังอัลกอริทึมมีดังต่อไปนี้ - แทนที่ตำแหน่งหน่วยความจำที่สองด้วย descriptor ซึ่งบอกว่าคุณต้องการทำอะไร จากนั้นระบุว่า descriptor มีอยู่ให้ตรวจสอบตำแหน่งหน่วยความจำแรกเพื่อดูว่ามีการเปลี่ยนแปลงค่าหรือไม่ หากไม่มีให้แทนที่ descriptor ที่ตำแหน่งหน่วยความจำที่สองด้วยค่าใหม่ มิฉะนั้นให้ตั้งค่าตำแหน่งหน่วยความจำที่สองกลับเป็นค่าเดิม
ผู้เขียนไม่ได้อธิบายว่าเหตุใดจึง!!
จำเป็นต้องใช้บรรทัดที่มีความคิดเห็นในบทความ ฉันดูเหมือนว่าCAS1
คำแนะนำในการComplete
ทำงานจะล้มเหลวเสมอหลังจากการตรวจสอบนี้โดยที่ไม่มีการแก้ไขพร้อมกัน และหากมีการเปลี่ยนแปลงเกิดขึ้นพร้อมกันระหว่างการตรวจสอบและ CAS ในComplete
แล้วด้ายทำการตรวจสอบจะยังคงล้มเหลวด้วย CAS ในตั้งแต่การปรับเปลี่ยนพร้อมกันไม่ควรใช้อธิบายเดียวกันComplete
d
คำถามของฉันคือสามารถตรวจสอบในฟังก์ชั่นRDCSSS
, if (r == d->o2)...
ถูกมองข้ามด้วย RDCSS ที่ยังคงรักษาความหมายของเปรียบเทียบคำแนะนำและแลกเปลี่ยนคู่เดียวซึ่งเป็นlinearizableและล็อคฟรี ? (เรียงตาม!!
ความคิดเห็น)
ถ้าไม่คุณสามารถอธิบายสถานการณ์ที่บรรทัดนี้จำเป็นจริง ๆ เพื่อความถูกต้องหรือไม่
ขอบคุณ.