อะไรคือข้อดีของรูปแบบ endian เล็ก ๆ น้อย ๆ ?


140

โปรเซสเซอร์ของ Intel (และอื่น ๆ ) อาจใช้รูปแบบ endian เล็กน้อยสำหรับการจัดเก็บ

ฉันมักจะสงสัยว่าทำไมบางคนต้องการเก็บไบต์ในลำดับที่กลับกัน รูปแบบนี้มีข้อดีมากกว่ารูปแบบ endian ใหญ่หรือไม่


1
6502 เป็นตัวประมวลผล pipelined ตัวแรก (ตัวแรก?) ฉันดูเหมือนจะจำข้อเรียกร้องบางอย่างเกี่ยวกับเรื่องนี้ว่าเป็นเรื่องเล็ก ๆ น้อย ๆ สำหรับปัญหาที่เกี่ยวข้องกับประสิทธิภาพเนื่องจากท่อส่งก๊าซ แต่ตอนนี้ฉันไม่มีความคิดว่าปัญหานั้นอาจเกิดขึ้นได้อย่างไร ข้อเสนอแนะใด ๆ
Steve314

1
@ Steve314: คำตอบของฉันอธิบายว่า endian ช่วยด้วยประสิทธิภาพในซีพียู pipelined: programmers.stackexchange.com/q/95854/27874
Martin Vilcans

3
Little-endian, big-endian - คุณต้องเลือกอย่างใดอย่างหนึ่ง เช่นเดียวกับการขับขี่ทางซ้ายหรือทางขวาของถนน

3
ฉันแนะนำให้คุณเขียนโค้ดใน ASM โดยเฉพาะอย่างยิ่งสำหรับสถาปัตยกรรม "โรงเรียนเก่า" เช่น 6502 หรือ Z80 คุณจะเห็นได้ทันทีว่าทำไมเหล่านี้ใช้ endian น้อย สถาปัตยกรรมที่ใช้ endian ใหญ่มีลักษณะบางอย่างกับชุดคำสั่งที่ทำให้รูปแบบนั้นดีกว่าแทน มันไม่ใช่การตัดสินใจโดยพลการ!
Stefan Paul Noack

2
แต่ละระบบสั่งไบต์มีข้อดีของมัน เครื่อง Little-endian ช่วยให้คุณอ่านไบต์ต่ำสุดก่อนโดยไม่ต้องอ่านค่าอื่น ๆ คุณสามารถตรวจสอบว่าเป็นเลขคี่หรือแม้กระทั่ง (บิตสุดท้ายเป็น 0) ได้อย่างง่ายดายมากซึ่งจะเจ๋งถ้าคุณเป็นสิ่งนั้น ระบบ Big-endian เก็บข้อมูลในหน่วยความจำแบบเดียวกับที่เราคิดเกี่ยวกับข้อมูล (จากซ้ายไปขวา) ซึ่งทำให้การดีบักระดับต่ำง่ายขึ้น
Koray Tugay

คำตอบ:


198

มีข้อโต้แย้งอย่างใดอย่างหนึ่ง แต่จุดหนึ่งคือในระบบเล็ก ๆ ที่อยู่ของค่าที่กำหนดในหน่วยความจำนำมาเป็นความกว้าง 32, 16, หรือ 8 บิตเหมือนกัน

กล่าวอีกนัยหนึ่งถ้าคุณมีหน่วยความจำสองค่าไบต์:

0x00f0   16
0x00f1    0

การใช้ '16' เป็นค่า 16 บิต (c 'short' ในระบบ 32 บิตส่วนใหญ่) หรือเป็นค่า 8 บิต (โดยทั่วไป c 'char') จะเปลี่ยนเฉพาะคำแนะนำการดึงข้อมูลที่คุณใช้ไม่ใช่ที่อยู่ที่คุณดึงข้อมูล จาก.

ในระบบ big-endian โดยที่ข้อความข้างต้นจัดเป็น:

0x00f0    0
0x00f1   16

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

ดังนั้นในระยะสั้น 'ในระบบ endian เล็ก ๆ น้อย ๆ ปลดเปลื้องเป็น no-op.


3
แน่นอนว่าไบต์ที่มีลำดับสูงที่คุณไม่ได้อ่านสามารถถูกละเว้นได้อย่างสมเหตุสมผล (เช่นคุณรู้ว่ามันเป็นศูนย์อยู่แล้ว)
Steve314

10
@ Steve314: ถ้าฉันอยู่ในการดาวน์สตรีม C จาก 32 ถึง 16 บิต (เช่น) ในระบบเสริม 2 ของ - ระบบส่วนใหญ่ - ไบต์ไม่จำเป็นต้องถูกละเว้น โดยไม่คำนึงถึงคุณค่าของพวกเขาฉันสามารถละเว้นพวกเขาและยังคงเป็นไปตามมาตรฐาน C และความคาดหวังของโปรแกรมเมอร์

9
@Stritzinger - เรากำลังพูดถึงชุดประกอบ / รหัสเครื่องที่สร้างขึ้นโดยคอมไพเลอร์ซึ่งไม่สามารถพกพาได้ รหัสภาษาระดับสูงกว่าในการคอมไพล์เป็นแบบพกพา - มันเพียงแค่คอมไพล์กับการดำเนินการที่แตกต่างกันในสถาปัตยกรรมที่แตกต่างกัน
jimwise

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

4
@dan_waterworth ไม่มากนัก - โปรดจำไว้ว่ากฎเลขคณิตของตัวชี้ใน C เป็นต้นและจะเกิดอะไรขึ้นเมื่อคุณเพิ่มหรือลดส่วนของตัวชี้ที่เหมือนกัน คุณสามารถย้ายความซับซ้อน แต่คุณไม่สามารถกำจัดมันได้
jimwise

45

ฉันมักจะสงสัยว่าทำไมบางคนต้องการเก็บไบต์ในลำดับที่กลับกัน

Big-endian และ little-endian เป็นเพียง "การสั่งซื้อปกติ" และ "การสั่งซื้อย้อนกลับ" จากมุมมองของมนุษย์และจากนั้นหากสิ่งเหล่านี้เป็นจริง ...

  1. คุณกำลังอ่านค่าบนหน้าจอหรือบนกระดาษ
  2. คุณใส่ที่อยู่หน่วยความจำต่ำลงทางซ้ายและที่อยู่สูงขึ้นทางด้านขวา
  3. คุณกำลังเขียนเลขฐานสิบหกโดยมีค่า nybble เรียงลำดับสูงอยู่ทางซ้ายหรือเลขฐานสองที่มีบิตที่สำคัญที่สุดอยู่ทางซ้าย
  4. คุณอ่านจากซ้ายไปขวา

สิ่งเหล่านี้ล้วนเป็นแบบแผนของมนุษย์ที่ไม่สำคัญเลยสำหรับซีพียู หากคุณต้องรักษา # 1 และ # 2 และพลิก # 3 ผู้เอนกายเล็ก ๆ จะดูเหมือน "เป็นธรรมชาติอย่างสมบูรณ์" สำหรับผู้ที่อ่านภาษาอาหรับหรือฮิบรูซึ่งเขียนจากขวาไปซ้าย

และยังมีการประชุมอื่น ๆ ของมนุษย์ที่ทำให้คนหัวโตที่ดูเหมือนไม่เป็นธรรมชาติเช่น ...

  • ไบต์ "สูงกว่า" (สำคัญที่สุด) ควรเป็นที่อยู่หน่วยความจำ "สูง"

ย้อนกลับไปตอนที่ฉันเขียนโปรแกรมส่วนใหญ่ 68K และ PowerPC ฉันคิดว่าบิ๊ก - เอนเดี้ยนเป็น "ถูกต้อง" และเอนด์ - เล็ก ๆ น้อย ๆ ที่จะ "ผิด" แต่เนื่องจากฉันได้ทำงานกับ ARM และ Intel มากขึ้นฉันจึงคุ้นเคยกับเด็กน้อย มันไม่สำคัญหรอก


30
ตัวเลขนั้นเขียนจาก [ตัวเลขที่สำคัญที่สุด] จากซ้ายไปเป็น [ตัวเลขที่มีนัยสำคัญน้อยที่สุด] ในภาษาอาหรับและฮิบรู
Random832

5
แล้วทำไมบิตภายในไบต์จัดเก็บในรูปแบบ "big endian" ทำไมไม่สอดคล้องกัน?
tskuzzy

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

3
BlueRaja: โดยการเขียนลงบนกระดาษเท่านั้น สิ่งนี้ไม่มีอะไรเหมือนกับสถาปัตยกรรม CPU คุณสามารถเขียนไบต์เป็น 0-7 LSB-MSB แทน 7-0 MSB-LSB และไม่มีอะไรเปลี่ยนแปลงจากมุมมองอัลกอริทึม
เอสเอฟ

2
@ SF: "กดสั้น ๆ ป๊อปอะไรก็ได้ แต่สั้น " จะทำให้คุณประหลาดใจอยู่ดี แม้ว่าคุณจะไม่ได้เสียหายของสแต็คโดยการผลักดันไบต์ที่คุณไม่เคยปรากฏหรือในทางกลับกัน ... x86 (32 บิต) เช่นจริงๆจริงๆต้องการสแต็คที่จะ DWORD ชิดและผลักดันหรือ popping อะไรที่เป็นสาเหตุของ ตัวชี้สแต็กที่ไม่ใช่ตัวคูณของ 4 อาจทำให้เกิดปัญหาการจัดตำแหน่ง และแม้ว่ามันจะไม่เป็นเช่นนั้นสิ่งต่าง ๆ ก็ผลักทั้งคำ / dword / qword / etc ทีละครั้งดังนั้นไบต์ต่ำจะยังคงเป็นคำแรกที่คุณได้รับเมื่อคุณปรากฏขึ้น
cHao

41

ตกลงนี่คือเหตุผลที่ฉันอธิบายให้ฉัน: การบวกและการลบ

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

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

นี่เป็นระบบ 8 บิตเก่า บน CPU ที่ทันสมัยฉันสงสัยว่าคำสั่งไบต์สร้างความแตกต่างและเราใช้ endian เพียงเล็กน้อยเพื่อเหตุผลทางประวัติศาสตร์


3
อ่า - มันเป็นเหตุผลเดียวกับที่ฉันใช้อันน้อยนิดสั่งให้เต็มจำนวนใหญ่ ฉันควรจะได้ผลที่ออกมา ผู้คนต้องการทำงานกับไซเบอร์เนติกส์จริงๆตอนนี้สมองของฉันมีความต้องการอะไหล่ทดแทนและการอัพเกรดที่รุนแรงฉันไม่สามารถรอได้ตลอดไป!
Steve314

2
ความคิด - 6502 ไม่ได้ทำคณิตศาสตร์ 16 บิตในฮาร์ดแวร์มากนักประมวลผล 8 บิต แต่มันก็ไม่ได้ทำญาติที่อยู่โดยใช้ 8 บิตลงนามชดเชยเทียบกับฐานที่อยู่ 16 บิต
Steve314

2
โปรดทราบว่าความคิดนี้ยังคงมีความสำคัญสำหรับการคำนวณเลขจำนวนเต็มที่มีความแม่นยำหลายอย่าง (ดังที่ Steve314 พูดไว้) แต่อยู่ที่ระดับคำ ขณะนี้การดำเนินการส่วนใหญ่ไม่ได้รับผลกระทบโดยตรงจาก endianness ของโปรเซสเซอร์: เรายังสามารถเก็บคำที่มีความสำคัญน้อยที่สุดเป็นอันดับแรกในระบบ big-endian เช่นเดียวกับที่ทำโดย GMP ตัวประมวลผลขนาดเล็กยังคงมีข้อได้เปรียบสำหรับการดำเนินการบางอย่าง (เช่นการแปลงสตริงหรือไม่) ที่สามารถทำได้ง่ายขึ้นโดยการอ่านทีละหนึ่งไบต์เนื่องจากในระบบแบบ end-endian เพียงลำดับไบต์นั้นหมายเลขที่ถูกต้องนั้น
vinc17

ตัวประมวลผลเล็ก ๆ น้อย ๆ มีข้อได้เปรียบในกรณีที่แบนด์วิดท์หน่วยความจำมี จำกัด เช่นในโปรเซสเซอร์ ARM แบบ 32 บิตที่มีบัสหน่วยความจำ 16 บิตหรือ 8088 กับบัสข้อมูล 8 บิต: โปรเซสเซอร์สามารถโหลดครึ่งต่ำและทำ เพิ่ม / sub / mul ... ด้วยขณะที่รอครึ่งที่สูงกว่า
phuclv

13

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

จะยังดีกว่าสำหรับการดำเนินการเพิ่มเติมหากคุณจัดการไบต์ในเวลา

แต่ไม่มีเหตุผลว่า big-endian นั้นเป็นธรรมชาติมากกว่า - ในภาษาอังกฤษคุณใช้สิบสาม (endian น้อย) และยี่สิบสาม (big endian)


1
Big-endian นั้นง่ายกว่าสำหรับมนุษย์เพราะมันไม่จำเป็นต้องมีการจัดเรียงไบต์ใหม่ ตัวอย่างเช่นบนพีซี0x12345678จะถูกเก็บไว้ใน78 56 34 12ขณะที่อยู่บนระบบ BE 12 34 56 78(ไบต์ 0 อยู่ทางซ้ายไบต์ 3 อยู่ทางขวา) สังเกตว่าจำนวนที่มากขึ้นนั้นเป็นอย่างไร (ในรูปของบิต) ยิ่งต้องมีการแลกเปลี่ยนมากขึ้น คำจะต้องมีการแลกเปลี่ยน; a DWORD, สองครั้งที่ผ่านไป (สามการสลับรวม); QWORD สามรอบ (รวม 7 ครั้ง) และอื่น ๆ นั่นคือการ(bits/8)-1แลกเปลี่ยน อีกทางเลือกหนึ่งคือการอ่านพวกเขาทั้งไปข้างหน้าและข้างหลัง (อ่านแต่ละไบต์ไปข้างหน้า แต่การสแกนทั้ง # ย้อนหลัง)
Synetech

หนึ่งร้อยและสิบสามเป็นทั้งกลาง - endian หรืออื่น ๆ ที่ใหญ่ endian กับ "สิบสาม" เป็นหลักหนึ่งไม่ใช่ตัวเลขทศนิยม เมื่อเราสะกดตัวเลขมีการเบี่ยงเบนเล็กน้อยจากอนุสัญญาพื้นฐานคงที่ที่เราใช้เป็นตัวเลข แต่เมื่อคุณ
แยกแยะ

@ Synetech- โชคดีที่คอมพิวเตอร์ไม่ต้องสนใจว่ามนุษย์อ่านมันอย่างไร นั่นเหมือนกับการอ้างว่าแฟลช NAND นั้นดีกว่าเนื่องจาก ot '
Martin Beckett

1
@ Steve314 คำที่สะกดออกมาของตัวเลขไม่สำคัญมันเป็นตัวเลขที่อ่านได้ซึ่งเป็นสิ่งที่เราใช้เมื่อเราตั้งโปรแกรม มาร์ตินไม่มีคอมพิวเตอร์ไม่ต้องสนใจว่ามนุษย์อ่านตัวเลข แต่ถ้ามนุษย์อ่านได้ง่ายการเขียนโปรแกรม (หรืองานอื่น ๆ ที่เกี่ยวข้อง) จะง่ายขึ้นและข้อบกพร่องและข้อบกพร่องบางอย่างสามารถลดหรือหลีกเลี่ยงได้
Synetech

@ steve314 และในภาษาเดนมาร์ก "95" ออกเสียงว่า "fem halvfems" (ห้ารวมทั้งยี่สิบสี่และครึ่ง)
Vatine

7

การประชุมวันที่ญี่ปุ่นคือ "big endian" - yyyy / mm / dd สิ่งนี้มีประโยชน์สำหรับการจัดเรียงอัลกอริทึมซึ่งสามารถใช้การเปรียบเทียบสตริงอย่างง่ายกับกฎตัวแรก - ตัว - - เป็นสิ่งที่สำคัญที่สุด

บางสิ่งที่คล้ายกันนั้นใช้กับหมายเลข big-endian ที่เก็บไว้ในระเบียนที่มีความสำคัญที่สุดในฟิลด์แรก ลำดับความสำคัญของไบต์ภายในเขตข้อมูลตรงกับความสำคัญของเขตข้อมูลภายในระเบียนดังนั้นคุณสามารถใช้ a memcmpเพื่อเปรียบเทียบระเบียนไม่สนใจมากไม่ว่าคุณจะเปรียบเทียบ longwords สองคำสี่คำหรือแปดไบต์แยกกัน

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

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

ฉันอาจรวมลิงก์ไปยังอุทธรณ์คลาสสิก ...

http://tools.ietf.org/rfcmarkup?url=ftp://ftp.rfc-editor.org/in-notes/ien/ien137.txt

แก้ไข

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

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

  2. การเพิ่มหรือลดขนาดของค่าหมายถึงการเพิ่ม / ลบชิ้นส่วนในตอนท้าย - ไม่จำเป็นต้องเลื่อนชิ้นขึ้น / ลง อาจจำเป็นต้องคัดลอกเนื่องจากการจัดสรรหน่วยความจำใหม่ แต่ไม่บ่อยครั้ง

สิ่งนี้ไม่มีความเกี่ยวข้องอย่างชัดเจนกับตัวประมวลผล - จนกว่า CPU จะสร้างด้วยการรองรับจำนวนเต็มจำนวนมากของฮาร์ดแวร์มันเป็นเรื่องของห้องสมุดอย่างแท้จริง


7

ไม่มีใครตอบว่าทำไมจึงต้องทำสิ่งนี้มากมายเกี่ยวกับผลที่ตามมา

พิจารณาโปรเซสเซอร์ 8 บิตซึ่งสามารถโหลดไบต์เดียวจากหน่วยความจำในรอบสัญญาณนาฬิกาที่กำหนด

ตอนนี้ถ้าคุณต้องการโหลดค่า 16 บิตลงไป (พูด) การลงทะเบียนเพียงหนึ่งบิตและ 16 บิตที่คุณมี - เช่นตัวนับโปรแกรมจากนั้นวิธีง่ายๆในการทำคือ:

  • โหลดไบต์จากตำแหน่งดึงข้อมูล
  • เลื่อนไบต์นั้นไปทางซ้าย 8 ที่
  • การดึงตำแหน่งหน่วยความจำเพิ่มขึ้น 1
  • โหลด byte ต่อไป (เข้าไปในส่วน low order ของ register)

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

ผลที่ตามมาก็คือสิ่งที่ 16 บิต (ไบต์คู่) จะถูกเก็บไว้ในคำสั่งมากที่สุด ..Least นั่นคือที่อยู่ที่เล็กกว่ามีไบต์ที่สำคัญที่สุด - endian ใหญ่มาก

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

ผลลัพธ์ของการพยายามไปสู่ ​​endian เล็ก ๆ น้อย ๆ ก็คือคุณต้องการซิลิคอนมากขึ้น (สวิตช์และประตู) หรือการทำงานที่มากขึ้น

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

วันนี้การพิจารณาเหล่านี้และไม่เกี่ยวข้องมากสวย แต่สิ่งต่าง ๆ เช่นการเติมไปป์ไลน์อาจยังคงเป็นเรื่องใหญ่

เมื่อพูดถึงการเขียน s / w ชีวิตมักจะง่ายขึ้นเมื่อใช้การจัดการกับ endian เล็กน้อย

(และโปรเซสเซอร์ endian ใหญ่มีแนวโน้มที่จะ endian ใหญ่ในแง่ของการสั่งซื้อไบต์และ endian เล็ก ๆ น้อย ๆ ในแง่ของบิตในไบต์. แต่การประมวลผลบางอย่างที่แปลกและจะใช้บิต endian ใหญ่การสั่งซื้อเช่นเดียวกับการสั่งซื้อไบต์. นี้ทำให้ชีวิตมากน่าสนใจสำหรับนักออกแบบ h / w ที่เพิ่มอุปกรณ์ต่อพ่วงหน่วยความจำที่แมป แต่ไม่มีผลอื่นใดเกิดขึ้นกับโปรแกรมเมอร์)


3

jimwise ทำให้เป็นจุดที่ดี มีปัญหาอื่นใน endian น้อยคุณสามารถทำสิ่งต่อไปนี้:

byte data[4];
int num=0;
for(i=0;i<4;i++)
    num += data[i]<<i*8; 

OR 

num = *(int*)&data; //is interpreted as

mov dword data, num ;or something similar it has been some time

ตรงไปข้างหน้ามากขึ้นสำหรับโปรแกรมเมอร์ที่ไม่ได้รับผลกระทบจากข้อเสียที่เห็นได้ชัดจากการเปลี่ยนตำแหน่งในหน่วยความจำ โดยส่วนตัวแล้วฉันพบว่า endian ใหญ่ ๆ จะกลับกันในสิ่งที่เป็นธรรมชาติ :) 12 ควรเก็บและเขียนเป็น 21 :)


1
นี่เป็นการพิสูจน์ว่ามันเร็วกว่า / ง่ายกว่าที่จะทำงานในรูปแบบใด ๆ ที่เป็นของ CPU มันไม่ได้พูดอะไรเกี่ยวกับว่ามันจะดีกว่า สิ่งเดียวกันนี้เกิดขึ้นกับ endian ตัวใหญ่: for(i=0; i<4; i++) { num += data[i] << (24 - i * 8); }สอดคล้องกับmove.l data, numCPU ตัวใหญ่ของ endian
Martin Vilcans

@martin: การลบที่น้อยกว่าจะดีกว่าในหนังสือของฉัน
Cem Kalyoncu

มันไม่สำคัญหรอกเพราะคอมไพเลอร์จะปลดลูปอยู่ดี ในกรณีใด ๆ ซีพียูจำนวนมากมีคำแนะนำการแลกเปลี่ยนไบต์เพื่อจัดการปัญหา
Martin Vilcans

ฉันไม่เห็นด้วย bcoz ใน endian ใหญ่ฉันจะทำ {num << = 8; num | = data [i]; } อย่างน้อยนี้ไม่จำเป็นต้องคำนวณจำนวนกะซ้ายโดยใช้มัล
Hayri Uğur Koltuk

@ali: รหัสของคุณจะทำการดำเนินการที่แน่นอนฉันเขียนและจะไม่ทำงานใน endian ใหญ่
Cem Kalyoncu

1

ฉันมักจะสงสัยว่าทำไมบางคนต้องการเก็บไบต์ในลำดับที่กลับกัน

เลขทศนิยมเขียนเป็น endian ใหญ่ นอกจากนี้วิธีที่คุณเขียนเป็นภาษาอังกฤษคุณเริ่มต้นด้วยตัวเลขที่สำคัญที่สุดและสำคัญที่สุดถัดไปเป็นสำคัญที่สุด เช่น

1234

คือหนึ่งพันสองร้อยสามสิบสี่

นี่เป็นวิธีที่ endian ใหญ่บางครั้งเรียกว่าระเบียบตามธรรมชาติ

ใน endian น้อยตัวเลขนี้จะเป็นหนึ่งสองหมื่นสามร้อยสี่พัน

อย่างไรก็ตามเมื่อคุณดำเนินการทางคณิตศาสตร์เช่นการบวกหรือการลบคุณจะเริ่มต้นด้วยการสิ้นสุด

  1234
+ 0567
  ====

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

เพื่อรองรับ endian ขนาดใหญ่ด้วยวิธีนี้คุณต้องใช้ตรรกะในการอ่านหน่วยความจำแบบย้อนกลับหรือคุณมีกระบวนการ RISC ซึ่งทำงานกับการลงทะเบียนเท่านั้น ;)

การออกแบบ Intel x86 / Amd x64 จำนวนมากเป็นเรื่องในอดีต


0

Big-endian มีประโยชน์สำหรับการดำเนินการบางอย่าง (การเปรียบเทียบ "bignums" ของน้ำพุความยาว octet เท่ากันกับใจ) Little-endian สำหรับผู้อื่น (อาจเพิ่ม "bignums" สองรายการ) ในท้ายที่สุดมันขึ้นอยู่กับสิ่งที่ฮาร์ดแวร์ CPU ได้รับการตั้งค่าโดยปกติจะเป็นหนึ่งหรืออื่น ๆ (ชิป MIPS บางตัวเป็น IIRC สามารถสลับได้ในการบูตเป็น LE หรือ BE)


0

เมื่อมีการจัดเก็บและถ่ายโอนที่มีความยาวผันแปรเท่านั้นที่เกี่ยวข้อง แต่ไม่มีเลขคณิตที่มีหลายค่า LE มักเขียนได้ง่ายกว่าในขณะที่ BE อ่านได้ง่ายกว่า

ลองทำการแปลง int-to-string (และย้อนกลับ) เป็นตัวอย่างที่เฉพาะเจาะจง

int val_int = 841;
char val_str[] = "841";

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

val_int = 841;
// Make sure that val_str is large enough.

i = 0;
do // Write at least one digit to care for val_int == 0
{
    // Constants, can be optimized by compiler.
    val_str[i] = '0' + val_int % 10;
    val_int /= 10;
    i++;
}
while (val_int != 0);

val_str[i] = '\0';
// val_str is now in LE "148"
// i is the length of the result without termination, can be used to reverse it

ตอนนี้ลองแบบเดียวกันตามลำดับ โดยปกติคุณจะต้องมีตัวหารอื่นที่มีกำลังมากที่สุด 10 สำหรับหมายเลขที่ระบุ (ที่นี่ 100) คุณต้องพบสิ่งนี้ก่อน สิ่งอื่น ๆ อีกมากมายที่ต้องทำ

การแปลงสตริงเป็น int ทำได้ง่ายขึ้นใน พ.ศ. เมื่อมันเป็นการดำเนินการเขียนย้อนกลับ เขียนเก็บหลักสำคัญที่สุดล่าสุดดังนั้นควรอ่านก่อน

val_int = 0;
length = strlen(val_str);

for (i = 0; i < length; i++)
{
    // Again a simple constant that can be optimized.
    val_int = 10*val_int + (val_str[i] - '0');
}

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

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

อีกตัวอย่างสำหรับการจัดเก็บ BE จะเป็นการเข้ารหัสแบบ UTF-8 และอื่น ๆ อีกมากมาย

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