it-swarm-tr.com

Küçük endian formatının avantajı nedir?

Intel işlemciler (ve belki de bazıları) depolama için küçük endian biçimini kullanır.

Birisinin baytları neden ters sırada saklamak istediğini merak ediyorum. Bu biçimin büyük endian biçimine göre bir avantajı var mı?

150
Cracker

Her iki durumda da argümanlar vardır, ancak bir nokta, küçük bir endian sisteminde, 32, 16 veya 8 bit genişlik olarak alınan bellekteki belirli bir değerin adresinin aynı olmasıdır.

Başka bir deyişle, bellekte iki bayt değeriniz varsa:

0x00f0   16
0x00f1    0

'16' değerini 16 bitlik bir değer olarak (çoğu 32 bitlik sistemde c 'kısa') veya 8 bitlik bir değer olarak (genellikle c 'char') yalnızca kullandığınız getirme talimatını değiştirir - aldığınız adresi değiştirmez dan.

Big-endian bir sistemde, yukarıdakiler şu şekilde düzenlenmiştir:

0x00f0    0
0x00f1   16

işaretçiyi artırmanız ve ardından yeni değer üzerinde daha dar getirme işlemini gerçekleştirmeniz gerekir.

Kısacası, little küçük endian sistemlerde, yayınlar işlemez. "

204
jimwise

Birisinin baytları neden ters sırada saklamak istediğini merak ediyorum.

Big-endian ve little-endian, sadece insan bakış açısından "normal düzen" ve "ters düzen" dir ve daha sonra ancak bunların hepsi doğru olduğunda ...

  1. Ekrandaki veya kağıt üzerindeki değerleri okuyorsunuz.
  2. Daha düşük bellek adreslerini sola, daha yüksek bellek adreslerini sağa koyarsınız.
  3. Solda yüksek dereceli nybble veya en önemli bit solda olmak üzere ikili olarak hex yazıyorsunuz.
  4. Soldan sağa okudunuz.

Bunların hepsi bir CPU için hiç önemli olmayan insan sözleşmeleridir. Eğer # 1 ve # 2'yi tutacak ve # 3'ü çevirecek olsaydınız, küçük endian, sağdan sola yazılan Arapça veya İbranice okuyan insanlar için "mükemmel derecede doğal" görünüyordu.

Ve büyük-endianı doğal olmayan görünen başka insan sözleşmeleri de var ...

  • "Daha yüksek" (en önemli) bayt "daha yüksek" bellek adresinde olmalıdır.

Daha çok 68K ve PowerPC programlarken, büyük-endianın "doğru" ve küçük-endianın "yanlış" olduğunu düşündüm. Ama daha fazla ARM ve Intel çalışması yaptığımdan beri, küçük endianlara alıştım, gerçekten önemli değil.

46
Bob Murphy

Tamam, bana açıklamamın nedeni şu: Toplama ve çıkarma

Çok baytlı sayıları eklediğinizde veya çıkardığınızda, en az önemli baytla başlamanız gerekir. Örneğin, iki adet 16 bit sayı ekliyorsanız, en az önemli bayttan en önemli bayta bir taşıma olabilir, bu nedenle bir taşıma olup olmadığını görmek için en az önemli baytla başlamanız gerekir. Bu, uzun el ekleme yaparken en sağdaki rakamla başlamanızın nedenidir. Soldan başlayamazsın.

Baytları bellekten sırayla alan 8 bitlik bir sistem düşünün. Önce en az önemli baytı getirirse , ekini yapmaya başlayabilir en önemli bayt bellekten alınır. Bu paralellik, sistem gibi küçük endianlarda performansın daha iyi olmasının nedenidir. Her iki baytın bellekten alınmasını veya ters sırada alınmasını beklemesi gerekiyorsa, daha uzun sürer.

Bu eski 8 bit sistemlerde. Modern bir CPU'da bayt sırasının herhangi bir fark yarattığından şüpheliyim ve sadece endianları sadece tarihsel nedenlerle kullanıyoruz.

44
Martin Vilcans

8 bit işlemcilerle kesinlikle daha verimliydi, farklı koda ihtiyaç duymadan ve ekstra değerler arabelleğe gerek kalmadan 8 veya 16 bitlik bir işlem gerçekleştirebilirsiniz.

Bir seferde bir bayt ile uğraşıyorsanız bazı ekleme işlemleri için hala daha iyidir.

Ancak big-endian'ın daha doğal olmasının bir nedeni yok - İngilizce'de on üç (küçük endian) ve yirmi üç (büyük endian) kullanıyorsunuz

13
Martin Beckett

Japon tarih sözleşmesi "büyük endian" dır - yyyy/aa/gg. Bu, sıradan ilk karakter-en önemli kuralı ile basit bir dize karşılaştırması kullanabilen algoritmaları sıralamak için kullanışlıdır.

Benzer bir şey, en önemli alan-ilk kayıtta saklanan büyük endian sayıları için de geçerlidir. Alanlardaki baytların önem sırası kayıttaki alanların önemiyle eşleşir, böylece kayıtları karşılaştırmak için memcmp kullanabilirsiniz, iki uzun kelimeyi, dört kelimeyi veya sekizini karşılaştırıp karşılaştırmamanıza önem vermeyin ayrı bayt.

Alanların önem sırasını ters çevirin ve aynı avantajı elde edin, ancak big-endian yerine küçük endian sayıları için.

Bunun elbette çok az pratik önemi var. Platformunuz ister big-endian ister küçük-endian olsun, gerçekten ihtiyacınız varsa bu numaradan yararlanmak için bir kayıt alanı sipariş edebilirsiniz. taşınabilir kod yazmanız gerekiyorsa sadece bir acıdır.

Ben de klasik çekiciliğe bir link ekleyebilirim ...

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

[~ # ~] düzenlemek [~ # ~]

Fazladan bir düşünce. Bir keresinde büyük bir tamsayı kütüphanesi yazdım (yapabildiğimi görmek için) ve bunun için, 32-bit genişliğindeki parçalar, platformun bu parçalardaki bitleri nasıl sipariş ettiğinden bağımsız olarak küçük endian düzeninde saklanır. Sebepler ...

  1. Bir çok algoritma doğal olarak en az önemli uçta çalışmaya başlar ve bu uçların eşleşmesini ister. Örneğin, ek olarak, gittikçe daha fazla anlamlı basamağa ulaşır, bu nedenle en az anlamlı sondan başlamak mantıklıdır.

  2. Bir değeri büyütmek veya küçültmek, yalnızca parçaların sonuna ekleme/çıkarma anlamına gelir - parçaları yukarı/aşağı kaydırmaya gerek yoktur. Bellek yeniden tahsisi nedeniyle kopyalama gerekebilir, ancak çoğu zaman gerekmez.

Bunun işlemcilerle açık bir ilgisi yok - CPU'lar donanım tam sayı desteği ile yapılana kadar, tamamen bir kütüphane işi.

7
Steve314

Kimse bunun NEDEN yapılabileceğini, sonuçlarla ilgili birçok şeyi yanıtlamadı.

Belirli bir saat döngüsünde bellekten tek bir bayt yükleyebilen 8 bitlik bir işlemci düşünün.

Şimdi, 16 bitlik bir değer yüklemek istiyorsanız, sahip olduğunuz tek 16 bitlik bir kayıt (yani) - yani program sayacı, bunu yapmanın basit bir yolu:

  • Getirme konumundan bir bayt yükleme
  • bu baytı sola 8 yere kaydır
  • bellek getirme konumunu 1 arttırır
  • sonraki baytı yükle (kaydın düşük dereceli kısmına)

sonuç: sadece getirme konumunu arttırırsınız, yalnızca daha geniş kaydın düşük dereceli kısmına yüklersiniz ve yalnızca sola kaydırmanız gerekir. (Tabii ki, sağa kaydırmak diğer işlemler için yararlıdır, bu yüzden bu bir yan gösteridir.)

Bunun bir sonucu olarak 16 bit (çift bayt) şeyler Most..Least. Yani, küçük adres en önemli bayta sahiptir - çok büyük endian.

Bunun yerine küçük endian kullanarak yüklemeyi denediyseniz, geniş kaydınızın alt kısmına bir bayt yüklemeniz, ardından bir sonraki baytı bir hazırlama alanına yüklemeniz, kaydırmanız ve daha sonra geniş kaydınızın üstüne yerleştirmeniz gerekir. . Veya seçici olarak üst veya alt bayta yükleyebilmek için daha karmaşık bir geçit düzeni kullanın.

Küçük endian almaya çalışmanın sonucu, daha fazla silikon (anahtarlar ve kapılar) veya daha fazla işleme ihtiyacınız olmasıdır.

Başka bir deyişle, eski günlerde paranın karşılığını almak açısından, çoğu performans ve en küçük silikon alanı için daha fazla patlama elde edersiniz.

Bugünlerde, bu düşünceler ve hemen hemen alakasız, ama boru hattı doldurmak gibi şeyler may hala biraz büyük bir anlaşma olabilir.

S/w yazmak söz konusu olduğunda, küçük endian adresleme kullanırken hayat genellikle daha kolaydır.

(Ve büyük endian işlemciler bayt sırası açısından büyük endian ve bayt bitleri açısından küçük endian olma eğilimindedir. Ancak bazı işlemciler gariptir ve büyük endian bit sıralaması ve bayt sıralaması kullanacaktır. çok bellek eşlemeli çevre birimleri ekleyen h/w tasarımcısı için ilginç, ancak programcı için başka bir sonucu yok.)

7
quickly_now

jimwise iyi bir noktaya değindi. Başka bir sorun daha var, küçük endianda aşağıdakileri yapabilirsiniz:

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

Bellekte yer değiştirilen yerlerin bariz dezavantajından etkilenmeyen programcılar için daha basittir. Şahsen ben doğal olanın tersine olmak için büyük endian buluyorum :). 12, 21 olarak depolanmalı ve yazılmalıdır :)

3
Cem Kalyoncu

Birisinin baytları neden ters sırada saklamak istediğini her zaman merak ediyorum

Ondalık sayı büyük endian olarak yazılır. Aynı zamanda İngilizce olarak nasıl yazdığınızı en önemli rakamla ve bir sonrakinden en önemlisi en az anlamlıya doğru başlarsınız. Örneğin.

1234

bin iki yüz otuz dörttür.

Büyük endian'a bazen doğal düzen denir.

Küçük endian'da bu sayı bir, yirmi, üç yüz dört bin olacaktı.

Ancak, toplama veya çıkarma gibi aritmetik gerçekleştirdiğinizde, sonla başlarsınız.

  1234
+ 0567
  ====

4 ve 7 ile başlıyorsunuz, en düşük rakamı yazıyorsunuz ve taşımayı hatırlıyorsunuz. Daha sonra 3 ve 6 vb. Eklersiniz. Toplama, çıkarma veya karşılaştırma için, hafızayı sırayla okumak için mantığınız varsa, sayılar ters çevrilirse, uygulamak daha kolaydır.

Büyük endianı bu şekilde desteklemek için belleği tersine okumak için mantığa ihtiyacınız var veya sadece kayıtlarda çalışan RISC işleminiz var. ;)

Intel x86/AMD x64 tasarımının çoğu tarihseldir.

1
Peter Lawrey

Big-endian bazı işlemler için yararlıdır (eşit sekizli uzunluktaki yayların "bignum" unun akılda tutulması). Diğerleri için Little-endian (muhtemelen iki "bignum" ekleyerek). Sonunda, CPU donanımının ne için ayarlandığına bağlıdır, genellikle biri veya diğeri (bazı MIPS yongaları IIRC, önyüklemede LE veya BE olarak değiştirilebilir).

0
Vatine

Yalnızca değişken uzunluklarda depolama ve aktarım söz konusu olduğunda, ancak birden fazla değere sahip aritmetik olmadığında, LE'nin yazılması genellikle daha kolay olurken, BE'nin okunması daha kolaydır.

Belirli bir örnek olarak bir dizi-dizge dönüşümü (ve geri) alalım.

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

İnt dizgeye dönüştürüldüğünde, en az anlamlı basamağın çıkarılması en anlamlı basamağa göre daha kolaydır. Hepsi basit bir uç koşulu ile basit bir döngüde yapılabilir.

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

Şimdi BE sırayla aynı deneyin. Genellikle, belirli bir sayı için (burada 100) 10'un en büyük gücünü tutan başka bir bölen gerekir. Bunu ilk önce bulmalısın elbette. Yapacak çok daha fazla şey.

Ters yazma işlemi olarak yapıldığında BE'de dize dönüşümü yapmak daha kolaydır. Write en son basamağı saklar, bu yüzden önce okunmalıdır.

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');
}

Şimdi LE sırayla aynısını yapın. Yine, 1 ile başlayan ve her basamak için 10 ile çarpılan ek bir faktöre ihtiyacınız olacaktır.

Bu nedenle genellikle depolama için BE kullanmayı tercih ederim, çünkü bir değer tam olarak bir kez yazılır, ancak en az bir kez ve belki de birçok kez okunur. Daha basit yapısı için, genellikle değeri ikinci kez yazsa bile LE'ye dönüştürme yoluna giderim ve ardından sonucu tersine çeviririm.

BE depolaması için başka bir örnek UTF-8 kodlaması ve daha fazlasıdır.

0
Secure