¿Cuál es la ventaja del formato little endian?

117

Los procesadores Intel (y quizás algunos otros) usan el formato little endian para el almacenamiento.

Siempre me pregunto por qué alguien querría almacenar los bytes en orden inverso. ¿Este formato tiene alguna ventaja sobre el formato big endian?

    
pregunta Cracker 24.07.2011 - 21:04

10 respuestas

176

Hay argumentos de cualquier manera, pero un punto es que en un sistema little-endian, la dirección de un valor dado en la memoria, tomada como ancho de 32, 16 u 8 bits, es la misma.

En otras palabras, si tiene en la memoria un valor de dos bytes:

0x00f0   16
0x00f1    0

tomar ese '16' como un valor de 16 bits (c 'corto' en la mayoría de los sistemas de 32 bits) o como un valor de 8 bits (generalmente c 'char') cambia solo la instrucción de recuperación que usa, no la dirección de la que obtiene.

En un sistema big-endian, con lo anterior descrito como:

0x00f0    0
0x00f1   16

necesitaría incrementar el puntero y luego realizar la operación de búsqueda más estrecha en el nuevo valor.

Así que, en resumen, "en los sistemas little endian, los modelos no son opcionales".

    
respondido por el jimwise 24.07.2011 - 22:04
37
  

Siempre me pregunto por qué alguien querría almacenar los bytes en orden inverso.

Big-endian y little-endian son solo "orden normal" y "orden inverso" desde una perspectiva humana, y solo si todos estos son verdaderos ...

  1. Estás leyendo los valores en la pantalla o en papel.
  2. Coloca las direcciones de memoria inferiores a la izquierda y las superiores a la derecha.
  3. Estás escribiendo en hexadecimal, con el nybble de orden superior a la izquierda, o binario, con el bit más significativo a la izquierda.
  4. Lees de izquierda a derecha.

Esas son todas las convenciones humanas que no importan en absoluto a una CPU. Si mantuvieras el número 1 y el número 2, y giraras el número 3, little-endian parecería "perfectamente natural" para las personas que leen árabe o hebreo, escritas de derecha a izquierda.

Y hay otras convenciones humanas que hacen que el big-endian parezca antinatural, como ...

  • El byte "más alto" (el más importante) debe estar en la dirección de memoria "más alta".

Cuando estaba programando principalmente 68K y PowerPC, consideraba que big-endian estaba "bien" y little-endian estaba "mal". Pero como he estado haciendo más trabajo de ARM e Intel, me he acostumbrado a little-endian. Realmente no importa.

    
respondido por el Bob Murphy 24.07.2011 - 23:14
32

Bien, esta es la razón por la que me lo explicaron: Suma y resta

Cuando sumas o restas números de múltiples bytes, debes comenzar con el byte menos significativo. Por ejemplo, si agrega dos números de 16 bits, puede haber un acarreo desde el byte menos significativo hasta el byte más significativo, por lo que debe comenzar con el byte menos significativo para ver si hay un acarreo. Esta es la misma razón por la que comienza con el dígito más a la derecha cuando realiza una suma a largo plazo. No puedes empezar desde la izquierda.

Considere un sistema de 8 bits que recupera bytes secuencialmente de la memoria. Si obtiene el byte menos significativo primero , puede comenzar a realizar la adición mientras el byte más significativo se obtiene de la memoria. Este paralelismo es la razón por la cual el rendimiento es mejor en little endian en sistemas como. Si tuviera que esperar hasta que se hubieran recuperado los dos bytes de la memoria, o recuperarlos en el orden inverso, tomaría más tiempo.

Esto es en sistemas antiguos de 8 bits. En una CPU moderna, dudo que el orden de los bytes haga alguna diferencia y usamos little endian solo por razones históricas.

    
respondido por el Martin Vilcans 25.07.2011 - 22:15
13

Con los procesadores de 8 bits sin duda fue más eficiente, podría realizar una operación de 8 o 16 bits sin necesidad de un código diferente y sin necesidad de almacenar valores adicionales.

Todavía es mejor para algunas operaciones de adición si está procesando un byte a la vez.

Pero no hay razón por la que big-endian sea más natural: en inglés usas trece (little endian) y veintitrés (big endian)

    
respondido por el Martin Beckett 24.07.2011 - 21:15
7

La convención de fecha japonesa es "big endian" - aaaa / mm / dd. Esto es útil para clasificar los algoritmos, que pueden usar una simple comparación de cadena con la regla más significativa de primer carácter habitual.

Algo similar se aplica a los números big-endian almacenados en un registro de primer campo más significativo. El orden de importancia de los bytes dentro de los campos coincide con la importancia de los campos dentro del registro, por lo que puede usar un memcmp para comparar registros, sin importar mucho si está comparando dos palabras largas, cuatro palabras u ocho bytes separados.

Cambia el orden de importancia de los campos y obtienes la misma ventaja, pero para los números little-endian en lugar de big-endian.

Esto tiene muy poco significado práctico, por supuesto. Ya sea que su plataforma sea big-endian o little-endian, puede ordenar campos de registros para explotar este truco si realmente lo necesita. Es un dolor si necesitas escribir el código portable .

También puedo incluir un enlace al llamamiento clásico ...

enlace

EDIT

Un pensamiento extra. Una vez escribí una gran biblioteca de enteros (para ver si podía), y para eso, los trozos de 32 bits de ancho se almacenan en orden little-endian, independientemente de cómo la plataforma ordena los bits en esos trozos. Las razones fueron ...

  1. Muchos algoritmos simplemente comienzan a funcionar en el extremo menos significativo, y desean que esos extremos coincidan. Por ejemplo, además, la propagación de datos se lleva a más y más dígitos significativos, por lo que tiene sentido comenzar en el extremo menos significativo.

  2. Aumentar o reducir un valor significa simplemente agregar / eliminar trozos al final, sin necesidad de desplazarlos hacia arriba o hacia abajo. Es posible que aún se necesite copiar debido a la reasignación de memoria, pero no a menudo.

Esto no tiene una relevancia obvia para los procesadores, por supuesto, hasta que las CPU se hacen con soporte de enteros de hardware, es puramente una cosa de biblioteca.

    
respondido por el Steve314 24.07.2011 - 22:42
6

Nadie más ha respondido POR QUÉ esto podría hacerse, muchas cosas sobre las consecuencias.

Considere un procesador de 8 bits que puede cargar un solo byte desde la memoria en un ciclo de reloj determinado.

Ahora, si desea cargar un valor de 16 bits, en (digamos) el único registro de 16 bits que tiene, es decir, el contador del programa, entonces una manera simple de hacerlo es:

  • Cargar un byte desde la ubicación de recuperación
  • desplaza ese byte a la izquierda 8 lugares
  • aumentar la ubicación de recuperación de memoria en 1
  • cargar el siguiente byte (en la parte de orden inferior del registro)

el resultado: solo incrementas la ubicación de recuperación, solo cargas en la parte de orden inferior de tu registro más amplio, y solo necesitas poder desplazarte hacia la izquierda. (Por supuesto, desplazarse a la derecha es útil para otras operaciones, por lo que esta es una demostración lateral).

Una consecuencia de esto es que las cosas de 16 bits (doble byte) se almacenan en el orden Most..Least. Es decir, la dirección más pequeña tiene el byte más significativo: el big endian.

Si en su lugar intentó cargar con little endian, tendría que cargar un byte en la parte inferior de su registro ancho, luego cargar el siguiente byte en un área de preparación, cambiarlo y luego colocarlo en la parte superior de su registro más amplio. O utilice una disposición de compuerta más compleja para poder cargar selectivamente en el byte superior o inferior.

El resultado de intentar ir a little endian es que necesitas más silicio (interruptores y puertas) o más operaciones.

En otras palabras, en términos de recuperarse en el pasado en los viejos tiempos, tiene más impacto en la mayoría del rendimiento y en el área de silicio más pequeña.

En estos días, estas consideraciones son bastante irrelevantes, pero cosas como el llenado de tuberías pueden ser un problema.

Cuando se trata de escribir s / w, la vida suele ser más fácil cuando se utiliza el direccionamiento little endian.

(Y los procesadores big endian tienden a ser big endian en términos de ordenamiento de bytes y little endian en términos de bits en bytes. Pero algunos procesadores son extraños y usarán el ordenamiento de bits big endian así como el ordenamiento de bytes. hace que la vida sea muy interesante para el diseñador de hardware al agregar periféricos asignados en memoria, pero no tiene ninguna otra consecuencia para el programador.)

    
respondido por el quickly_now 25.07.2011 - 06:44
3

jimwise hizo un buen punto. Hay otro problema, en little endian puedes hacer lo siguiente:

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

Más sencillo para los programadores que no se ven afectados por la obvia desventaja de las ubicaciones intercambiadas en la memoria. Personalmente encuentro que big endian es inverso a lo que es natural :). 12 deben almacenarse y escribirse como 21 :)

    
respondido por el Cem Kalyoncu 24.07.2011 - 23:06
1
  

Siempre me pregunto por qué alguien querría almacenar los bytes en orden inverso

El número decimal se escribe big endian. También cómo lo escribe en inglés. Usted comienza con el dígito más significativo y el siguiente, el más significativo, el menos significativo. por ejemplo

1234

es mil doscientos treinta y cuatro.

Esta es la forma en que el big endian a veces se denomina orden natural.

En little endian, este número sería uno, veinte, trescientos cuatro mil.

Sin embargo, cuando realizas operaciones aritméticas como la suma o la resta, comienzas con el final.

  1234
+ 0567
  ====

Empiezas con 4 y 7, escribe el dígito más bajo y recuerda el acarreo. Luego agrega 3 y 6, etc. Para agregar, restar o comparar, es más fácil de implementar, si ya tiene lógica para leer la memoria en orden, si se invierten los números.

Para admitir Big End de esta manera, necesita lógica para leer la memoria al revés, o tiene un proceso RISC que solo opera en los registros. ;)

Gran parte del diseño de Intel x86 / Amd x64 es histórico.

    
respondido por el Peter Lawrey 26.07.2011 - 08:49
0

Big-endian es útil para algunas operaciones (comparaciones de "bignums" de muelles de octetos de igual longitud a la mente). Little-endian para otros (añadiendo dos "bignums", posiblemente). Al final, depende de para qué se haya configurado el hardware de la CPU, generalmente es uno u otro (algunos chips MIPS fueron, IIRC, conmutable en el arranque para ser LE o BE).

    
respondido por el Vatine 25.07.2011 - 17:34
0

Cuando solo están involucrados el almacenamiento y la transferencia con longitudes variables, pero no la aritmética con múltiples valores, entonces LE suele ser más fácil de escribir, mientras que BE es más fácil de leer.

Tomemos una conversión int-to-string (y viceversa) como un ejemplo específico.

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

Cuando el int se convierte a la cadena, entonces el dígito menos significativo es más fácil de extraer que el dígito más significativo. Todo se puede hacer en un bucle simple con una condición final simple.

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] = '
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');
}
'; // val_str is now in LE "148" // i is the length of the result without termination, can be used to reverse it

Ahora intente lo mismo en el orden BE. Por lo general, necesita otro divisor que tenga la mayor potencia de 10 para el número específico (aquí 100). Primero necesitas encontrar esto, por supuesto. Mucho más cosas que hacer.

La conversión de cadena a int es más fácil de hacer en BE, cuando se realiza como la operación de escritura inversa. Write almacena el último dígito más significativo, por lo que debe leerse primero.

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

Ahora haz lo mismo en orden LE. Una vez más, necesitará un factor adicional que comience con 1 y se multiplique por 10 por cada dígito.

Por lo tanto, generalmente prefiero usar BE para el almacenamiento, porque un valor se escribe exactamente una vez, pero se lee al menos una vez y tal vez muchas veces. Por su estructura más simple, generalmente también tomo la ruta para convertir a LE y luego invierto el resultado, incluso si escribe el valor una segunda vez.

Otro ejemplo para el almacenamiento BE sería la codificación UTF-8, y muchos más.

    
respondido por el Secure 12.11.2012 - 12:30

Lea otras preguntas en las etiquetas