พวกเขาเสนอให้รวมการใช้งาน memchr . ในเคอร์เนล Linux เร็วขึ้นถึง 4 เท่า

เมื่อเร็ว ๆ นี้ ข้อเสนอสำหรับเคอร์เนลลินุกซ์ได้รับการเผยแพร่โดยเสนอให้รวมชุดของแพตช์ที่มี a การใช้งานฟังก์ชัน memchr() ที่เหมาะสมที่สุด ใช้เพื่อค้นหาอักขระในอาร์เรย์

ฟังก์ชัน memchr() จะสแกนนำหน้า n ไบต์ของพื้นที่หน่วยความจำที่ชี้ไปที่ s สำหรับอินสแตนซ์แรกของ c ทั้ง c และไบต์ในพื้นที่หน่วยความจำที่ชี้โดย s จะถูกตีความว่าเป็นอักขระที่ไม่ได้ลงนาม

ข้อเสนอ สัญญาว่า เร็วขึ้น เพื่อค้นหาตัวละครภายในบล็อกแห่งความทรงจำ ในการทดสอบของนักพัฒนาซอฟต์แวร์ การปรับใช้ใหม่สามารถทำได้เร็วขึ้นเกือบสี่เท่าในการค้นหาจำนวนมาก

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

ชุดของแพตช์นี้ปรับให้เหมาะสม "memcr()" และเพิ่มมาโครสำหรับ
"memchr_inv()" เพื่อให้ทั้งสองฟังก์ชันใช้สร้างบิตมาสก์ได้

การใช้งานดั้งเดิมของ "memcr()" ขึ้นอยู่กับการเปรียบเทียบไบต์
ซึ่งไม่ได้ใช้รีจิสเตอร์ 64 หรือ 32 บิตใน CPU อย่างเต็มที่ เราใช้ a
เปรียบเทียบโดยคำเพื่อให้สามารถเปรียบเทียบได้อย่างน้อย 4 ไบต์
สภาพอากาศ. memchr() ที่ปรับให้เหมาะสมนั้นเร็วกว่าต้นฉบับเกือบ 4 เท่า
สำหรับโซ่ยาว ใน Linux Kernel เราพบว่าความยาวของสตริง
ค้นหาโดย "memchr()" สูงสุด 512 ไบต์ใน drivers/misc/lkdtm/heap.c

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

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

เป็นมูลค่าการกล่าวขวัญว่าเวอร์ชันดั้งเดิมของ memchr() ถูกนำไปใช้กับเทคนิคการเปรียบเทียบแบบไบต์ ซึ่งไม่ได้ใช้รีจิสเตอร์บนซีพียู 64 บิตหรือ 32 บิตอย่างเต็มที่

เราใช้การเปรียบเทียบทั้งคำเพื่อให้สามารถเปรียบเทียบอักขระได้ 8 ตัวพร้อมกันบน CPU รหัสนี้อิงตามการใช้งานของ David Light

เราสร้างไฟล์สองไฟล์เพื่อวัดประสิทธิภาพของไฟล์แรก ซึ่งประกอบด้วยอักขระที่อยู่ข้างหน้าอักขระปลายทางโดยเฉลี่ย 10 ตัว ไฟล์ที่สองมีอย่างน้อย 1000 อักขระก่อน ตัวละครเป้าหมาย

การใช้งาน "memcr()" ของเรานั้นเล็กน้อย ดีกว่าในการทดสอบครั้งแรกและเร็วกว่าต้นฉบับเกือบ 4 เท่า การดำเนินการในการทดสอบครั้งที่สอง

การทดสอบเคอร์เนล 5.18 ด้วยตัวแปร "memchr()" ใหม่สำหรับสถาปัตยกรรม 32 บิตและ 64 บิต ไม่ได้เปิดเผยปัญหาใดๆ

จะเกิดอะไรขึ้นถ้า p ไม่ใช่ 8 (หรือ 4 บนเป้าหมาย 32 บิต) จัดตำแหน่งไบต์? เป้าหมายทั้งหมดไม่สนับสนุนการโหลดที่ไม่สอดคล้อง (มีประสิทธิภาพ) ใช่ไหม
 ฉันคิดว่ามันใช้งานได้ถ้า p ไม่เรียงกันเป็น 8 หรือ 4 ไบต์ สมมติว่าสตริงมีขนาด 10 ไบต์ for loop ที่นี่จะมองหา 8 ไบต์แรก หากอักขระปลายทางอยู่ใน 2 ไบต์สุดท้าย ตัวที่สองสำหรับลูปจะพบ มันยังทำงานในลักษณะนี้บนเครื่อง 32 บิต

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

ในที่สุด หากคุณสนใจที่จะทราบข้อมูลเพิ่มเติม คุณสามารถตรวจสอบรายละเอียด ในลิงค์ต่อไปนี้.


แสดงความคิดเห็นของคุณ

อีเมล์ของคุณจะไม่ถูกเผยแพร่ ช่องที่ต้องการถูกทำเครื่องหมายด้วย *

*

*

  1. ผู้รับผิดชอบข้อมูล: Miguel ÁngelGatón
  2. วัตถุประสงค์ของข้อมูล: ควบคุมสแปมการจัดการความคิดเห็น
  3. ถูกต้องตามกฎหมาย: ความยินยอมของคุณ
  4. การสื่อสารข้อมูล: ข้อมูลจะไม่ถูกสื่อสารไปยังบุคคลที่สามยกเว้นตามข้อผูกพันทางกฎหมาย
  5. การจัดเก็บข้อมูล: ฐานข้อมูลที่โฮสต์โดย Occentus Networks (EU)
  6. สิทธิ์: คุณสามารถ จำกัด กู้คืนและลบข้อมูลของคุณได้ตลอดเวลา