แทนที่คิวใน RTOS


12

สำหรับการสื่อสารระหว่างงานหรือแบ่งปันข้อมูลระหว่างสองงานของ RTOS เราใช้ Queues แต่ปัญหาเกี่ยวกับคิวก็คือพวกมันช้า .... พวกเขาคัดลอกข้อมูลใน Buffer จากนั้นจัดการ Mutex และ Data Transfer มันช้าอย่างน่ารำคาญถ้าคุณต้องถ่ายโอนข้อมูลขนาดใหญ่ ปัญหาอื่นคือถ้าเข้าถึงคิวเดียวกันโดยงานหลาย ๆ งาน จากนั้นรูปภาพจะเป็นดังนี้: - ก่อนอื่นรอการเข้าถึง The Queue จากนั้นจัดการคิว Mutex ภายในจากนั้นทำการถ่ายโอนข้อมูล

สิ่งนี้จะเพิ่มค่าใช้จ่ายในระบบ สิ่งที่สามารถทดแทนที่มีประสิทธิภาพสำหรับคิว?

(ฉันเดาว่าคำถามนี้เป็นอิสระจาก RTOS ที่เราใช้ส่วนใหญ่ RTOS จัดการกับคิวด้วยวิธีนี้เท่านั้น)


คุณหมายถึงคิวที่เข้าถึงได้โดยหลายงาน คุณหมายถึงการโพสต์ไปที่คิวหรืออ่านจากคิว? งานหลายอย่างควรสามารถโพสต์ไปยังคิวที่มีค่าใช้จ่ายน้อยที่สุด RTOS ควรจัดการ mutexing เพื่อให้การโพสต์เป็นการดำเนินการปรมาณู สำหรับ 99% ของงานคุณควรมีการวนรอบที่รอคิวและประมวลผลข้อความ คิวควร (ปกติ) อ่านโดยงานเดียวเท่านั้น คุณอาจต้องดูการออกแบบของคุณและวิธีใช้คิวแทนการออกแบบ
Erik

@Erik: ขออภัย! ฉันใช้กลไกที่คุณพูดถึง .... ฉันอยากจะพูดอย่างอื่นและฉันเขียนต่างออกไป .... ฉันจะแก้ไขมัน !! ขอบคุณสำหรับการชี้ให้เห็นความผิดพลาด! ฉันกำลังรอการเข้าถึงคิวในรหัสของฉัน!
Swanand

คำตอบ:


7

คิวดำเนินการด้วยวิธีนี้เนื่องจากเป็นรูปแบบธุรกรรมที่ปลอดภัยสำหรับการสื่อสารระหว่างภารกิจ คุณเสี่ยงต่อความเสียหายของข้อมูลและ / หรือปัญหาการเป็นเจ้าของในรูปแบบที่เข้มงวดน้อยกว่า

คุณกำลังคัดลอกข้อมูลลงในบัฟเฟอร์ในหน่วยความจำแล้วส่งต่อตัวชี้ด้วยองค์ประกอบคิวหรือพยายามส่งข้อมูลทั้งหมดในองค์ประกอบคิวเอง หากคุณไม่ได้ผ่านพอยน์เตอร์คุณจะได้รับประสิทธิภาพเพิ่มขึ้นแทนที่จะส่งไบต์ละหนึ่งครั้งผ่านองค์ประกอบคิว


2
ฉันจะพูดในสิ่งเดียวกัน หากคุณเพิ่งส่งพอยน์เตอร์ไปยังข้อมูลในคิวคุณสามารถเพิ่มความเร็วได้ แต่ต้องแน่ใจว่าคุณไม่ได้จบด้วยเธรดสองตัวที่พยายามใช้และเปลี่ยนข้อมูล
Kortuk

ตามที่ @Kortuk กล่าวว่าฉันต้องการ "ให้แน่ใจว่าคุณไม่ได้จบด้วยสองกระทู้พยายามใช้และเปลี่ยนข้อมูล" ... ซึ่งหมายถึงการเพิ่มขึ้นของค่าใช้จ่าย ... ฉันไม่ต้องการการประมวลผลมาก! :(
Swanand

ดังนั้นจึงไม่มีการแทนที่คิว ... แทนที่จะเป็นคิวข้อมูลฉันต้องใช้ Pointer Queue!
Swanand

1
@Swanand หากวางแผนใบสมัครของคุณว่าคิวนั้นเป็นแบบทิศทางเดียว (เช่นคุณไม่เคยอ่านคิวเดียวกันในสองภารกิจ) และคุณประมวลผลข้อมูลที่เก็บไว้ที่ตัวชี้ทันทีแล้วปล่อยให้เป็นอิสระคุณไม่ควรมีปัญหาในการแบ่งปันข้อมูล จะมีค่าใช้จ่ายเพิ่มขึ้นเนื่องจากคุณอาจต้องสร้างหลาย ๆ คิวเพื่อส่งผ่านข้อมูลไปมาได้อย่างน่าเชื่อถือ แต่นี่เป็นค่าใช้จ่ายในการทำธุรกิจในสภาพแวดล้อมที่ทำงานหลายอย่าง
AngryEE

7

วิธีที่ง่ายวิธีหนึ่งคือการวางตัวชี้ไปยังข้อมูลบนคิวและใช้ข้อมูลโดยใช้ตัวชี้

โปรดทราบว่าคุณกำลังแลกเปลี่ยนความปลอดภัยเพื่อประสิทธิภาพด้วยวิธีนี้เนื่องจากคุณต้องแน่ใจว่า

  1. บัฟเฟอร์ยังคงใช้งานได้จนกว่าผู้บริโภคจะใช้ข้อมูล
  2. บางคนยกเลิกการจัดสรรบัฟเฟอร์

หากคุณไม่ได้ใช้หน่วยความจำที่จัดสรรแบบไดนามิกคุณไม่จำเป็นต้องจัดสรรคืน แต่คุณยังต้องตรวจสอบให้แน่ใจว่าพื้นที่หน่วยความจำไม่ได้ถูกนำมาใช้ซ้ำก่อนที่ข้อมูลจะถูกใช้


6

คิวที่ไม่มีการล็อคสามารถนำไปใช้กับกรณีผู้ผลิตรายเดียว / ผู้บริโภครายเดียวและบ่อยครั้งที่คุณสามารถออกแบบซอฟต์แวร์ของคุณเพื่อลดจำนวนผู้ผลิตหลายรายหรือผู้บริโภคหลายราย

คิวที่ไม่มีล็อคสามารถสร้างได้ดังนี้: จัดสรรอาเรย์ขององค์ประกอบที่จะสื่อสารและจำนวนเต็มสองจำนวนเรียกพวกเขาว่า Head and Tail ส่วนหัวคือดัชนีในอาร์เรย์ซึ่งจะเพิ่มรายการถัดไป Tail เป็นดัชนีในอาร์เรย์ซึ่งมีรายการถัดไปที่สามารถลบได้ งานผู้สร้างอ่าน H และ T เพื่อพิจารณาว่ามีที่ว่างสำหรับเพิ่มรายการหรือไม่ เขียนรายการในที่ดัชนี H จากนั้นอัพเดต H. งานของผู้บริโภคอ่าน H และ T เพื่อตรวจสอบว่ามีข้อมูลที่มีอยู่อ่านข้อมูลจากดัชนี T หรือไม่จากนั้นอัปเดต T โดยทั่วไปแล้วมันเป็นบัฟเฟอร์วงแหวนที่เข้าถึงได้โดยสองงาน คำสั่งของการดำเนินการ (แทรกแล้วอัปเดต H ลบแล้วอัปเดต T) รับรองว่าข้อมูลจะไม่เกิดความเสียหาย

หากคุณมีสถานการณ์ที่มีผู้ผลิตหลายรายและผู้บริโภครายเดียวหรือผู้ผลิตรายเดียวและผู้บริโภคหลายรายคุณมีข้อ จำกัด ด้านทรัพยากรอย่างมีประสิทธิภาพและไม่มีอะไรอื่นนอกจากการใช้การซิงโครไนซ์เนื่องจากตัว จำกัด ประสิทธิภาพมีแนวโน้มที่จะ เป็นผู้ผลิต / ผู้บริโภคที่โดดเดี่ยวกว่าค่าใช้จ่าย OS ด้วยกลไกการล็อค

แต่ถ้าคุณมีผู้ผลิตและผู้บริโภคหลายคนมันคุ้มค่าที่จะใช้เวลา (ในพื้นที่การออกแบบ) เพื่อดูว่าคุณไม่สามารถใช้กลไกการสื่อสารที่ประสานงานกันมากขึ้นหรือไม่ ในกรณีเช่นนี้การเรียงลำดับทุกอย่างผ่านคิวเดียวจะทำให้ประสิทธิภาพของคิวเป็นตัวกำหนดศูนย์กลางของประสิทธิภาพ


1
ฉันกำลังจะ +1 สิ่งนี้ แต่คุณไม่ถูกต้อง: คิวที่ปราศจากการล็อกสามารถนำไปใช้กับผู้อ่านและนักเขียนหลายคนพวกเขามีความซับซ้อนมากขึ้น (ดูกระดาษของ Michael + Scott บนคิวการล็อคฟรีgoogle.com/search?q=michael%20scott%20queue% )
Jason S

1
@Jason S - กระดาษสกอตต์อ้างสิทธิ์ในการแทรกและลบการล็อกโดยเฉพาะหรือไม่? ถ้าเป็นเช่นนั้นหากคุณสามารถแยกมันออกมาและโพสต์ได้โปรดทำเช่นนั้นมันจะเป็นสินทรัพย์ที่มีค่าสำหรับหลาย ๆ คน ผู้อ่านควรทราบว่ากระดาษที่อ้างถึงใช้ประโยชน์จากคำสั่งเครื่องพิเศษในขณะที่ตำแหน่งของฉันในการโพสต์ข้างต้นถือว่าไม่มีคำแนะนำดังกล่าว
JustJeff

1
ใช่ค่าใช้จ่ายของอัลกอริทึมล็อคฟรีมักจะพึ่งพา CAS หรือคำแนะนำที่เทียบเท่า แต่การเข้าร่วมอีกครั้งเข้ามาเล่นที่นี่ได้อย่างไร? มันสมเหตุสมผลสำหรับ mutexes + โครงสร้างการล็อก แต่ไม่ใช่สำหรับการดำเนินการโครงสร้างข้อมูล
Jason S

2

หนึ่งสามารถทำงานได้อย่างมีประสิทธิภาพในคิวผู้บริโภครายเดียวที่ไม่มีล็อคแบบล็อคหากคิวตัวเองถือไอเท็มที่มีขนาดเล็กพอที่จะทำงานกับโหลดสโตร์แบบเอกสิทธิ์เฉพาะบุคคลเปรียบเทียบแบบแลกเปลี่ยนหรือแบบดั้งเดิมที่คล้ายคลึงกันได้ ค่าที่สงวนไว้หรือค่าที่สงวนไว้สำหรับสล็อตคิวว่าง เมื่อเขียนไปที่คิวผู้เขียนทำการเปรียบเทียบการแลกเปลี่ยนเพื่อพยายามเก็บข้อมูลของเขาลงในช่องว่างถัดไป หากล้มเหลวผู้เขียนจะลองช่องต่อไปนี้ แม้ว่าคิวจะรักษาตัวชี้ไปยังช่องว่างถัดไป แต่ค่าตัวชี้คือ "คำแนะนำ" โปรดทราบว่าหากระบบใช้การเปรียบเทียบการแลกเปลี่ยนมากกว่าการโหลดร้านค้าพิเศษมันอาจจำเป็นต้องมี 'ตระกูล' ที่มีค่า 'ช่องว่างที่แตกต่างกัน' มิฉะนั้นหากในช่วงเวลาที่ผู้เขียนพบช่องว่างคิวและพยายามที่จะเขียนมัน นักเขียนคนอื่นเขียนสล็อตและผู้อ่านอ่านมันผู้เขียนคนแรกจะใส่ข้อมูลของเขาในจุดที่ผู้อ่านไม่เห็น ปัญหานี้ไม่ได้เกิดขึ้นในระบบที่ใช้ load-store-exclusive เนื่องจาก store-exclusive จะตรวจพบว่าข้อมูลถูกเขียนถึงแม้ว่ามันจะถูกเขียนกลับไปเป็นค่าเก่าก็ตาม


1

คุณสามารถเข้าถึงคิวได้อย่างมีประสิทธิภาพมากขึ้นโดยการเขียนที่ด้านบนของคิวปกติ RTOS ส่วนใหญ่จะให้การสนับสนุนในการเพิ่มที่ด้านหน้าของคิวซึ่งไม่ต้องการรับ mutex แต่ให้แน่ใจว่าคุณใช้การเพิ่มที่ด้านหน้าของคิวให้น้อยที่สุดเท่าที่จะเป็นไปได้ซึ่งคุณเพียงแค่ต้องการเรียกใช้ข้อมูลได้เร็วขึ้น โดยปกติโครงสร้างคิวจะมีขีด จำกัด ขนาดสูงสุดดังนั้นคุณอาจไม่ใส่ข้อมูลทั้งหมดในคิวดังนั้นการส่งผ่านตัวชี้จึงเป็นเรื่องง่ายเสมอ

ไชโย !!


1

คิวไม่ได้ช้าโดยเนื้อแท้ การดำเนินการของพวกเขาอาจจะ

หากคุณคัดลอกข้อมูลแบบสุ่มและใช้คิวแบบซิงโครนัสคุณจะเห็นประสิทธิภาพการทำงานดีขึ้น

ตามที่ผู้โพสต์คนอื่น ๆ ระบุไว้มีทางเลือกที่ไม่ล็อค กรณีผู้ผลิตเดี่ยว / ผู้บริโภครายเดียวนั้นตรงไปตรงมา สำหรับผู้ผลิตและผู้บริโภคหลายที่อัลกอริทึมคิวล็อคฟรีโดยไมเคิลและสกอตต์ (ผู้ที่มีชื่อสุดท้ายของพวกเขา) เป็นมาตรฐานและมีการใช้เป็นพื้นฐานสำหรับ Java ของConcurrentLinkedQueue

เป็นไปได้ที่จะปรับความต้องการคิวในบางกรณี แต่ให้การรับประกันพร้อมกันที่มักจะให้ประโยชน์ที่ง่ายมากสำหรับระบบโดยอนุญาตให้คุณแยกงานออกได้


จากกระดาษ Michael & Scott: "มันเป็นอัลกอริธึมที่ชัดเจนของทางเลือกสำหรับเครื่องจักรที่มีอะตอมมิกแบบดั้งเดิม (เช่นการเปรียบเทียบและแลกเปลี่ยนหรือโหลดการเชื่อมโยง / เงื่อนไขการจัดเก็บ)" แม้ว่าสิ่งนี้อาจไม่ล็อคเธรดอย่างแน่นอน แต่ก็มีรูปแบบการซิงโครไนซ์ที่เกิดขึ้นที่นี่
JustJeff

คุณมีประเด็น; มันอาจลดข้อกำหนดที่เกิดขึ้นพร้อมกันจากการเข้าถึงแบบเอกสิทธิ์เฉพาะบุคคลไปยังอุปสรรคหน่วยความจำ
Jason S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.