59 votos

¿Por qué no hay `nand de instrucción en las Cpu modernas?

¿Por qué diseñadores de x86 (o la arquitectura de la CPU, así como decidir no incluir? Es una puerta lógica que puede ser utilizado para construir otras puertas de la lógica, por lo que es rápido como una sola instrucción. En lugar de encadenar not y and instrucciones (ambos son creados a partir de nand), ¿por qué no nand a la enseñanza?.

66voto

jns Puntos 449

http://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.alangref/idalangref_nand_nd_instrs.htm : el PODER ha NAND.

Pero en general las Cpu modernas están construidas para que coincida automatizado de generación de código por parte de los compiladores, y bit a bit de la NAND que es muy rara vez. Bit a bit Y y O se utiliza más a menudo para la manipulación de los campos de bits en estructuras de datos. De hecho, la ESS tiene Y-NO, pero no NAND.

Cada instrucción tiene un costo en la descodificación de la lógica y consume un código de operación que podría ser utilizado para algo más. Especialmente en la longitud variable de las codificaciones como x86, puede ejecutar fuera de la corta opcodes y tienen que usar más tiempo, que potencialmente se ralentiza todo el código.

32voto

GetFree Puntos 495

El coste de un ALU funciones es

1) la lógica que realiza la misma función

2) el selector que se selecciona esta función, como resultado, en lugar de los otros fuera de todas las funciones de ALU

3) el costo de tener esta opción en el conjunto de instrucciones (y no tener alguna otra útil función)

Estoy de acuerdo con usted en que el 1) el costo es muy pequeño. El 2) y 3) el costo, sin embargo, es casi independiente de la función. Creo que en este caso el 3) costo (los bits ocupado en la instrucción), fueron la razón de no tener esta instrucción específica. Bits en una instrucción son un recurso muy escaso para un CPU de arquitectura/diseñador.

30voto

Brian Drummond Puntos 27798

La vuelta a su alrededor - primera ver por qué Nand fue popular en hardware el diseño de la lógica - que tiene varias propiedades útiles que hay. Luego, preguntarse si esas propiedades se aplica en una instrucción del procesador...

TL/DR - ellos no, así que no hay inconveniente para el uso de Y, O o No en su lugar.

La mayor ventaja al cableado Nand logic fue la velocidad, obtenido por la reducción del número de niveles lógicos (transistores) entre un circuito de entradas y salidas. En una CPU, la velocidad de reloj es determinado por la velocidad de mucho más complejo de operaciones como la suma, así que acelerar una operación Y no permite aumentar la velocidad del reloj.

Y el número de veces que es necesario combinar el resto de instrucciones es muy pequeña - lo suficiente para que la Nand realmente no gana su espacio en la instrucnion conjunto.

12voto

DmitrySandalov Puntos 129

Me gustaría estar de acuerdo con Brian aquí, y Wouter y pjc50.

También me gustaría añadir que en los de propósito general, especialmente CISC, los procesadores, las instrucciones no todos tienen el mismo rendimiento – una complicada operación puede simplemente tomar ciclos más que fácil.

Considere la posibilidad de X86: AND (que es una operación de "y") es, probablemente, muy rápido. Lo mismo va para NOT. Veamos un poco de desmontaje:

El código de entrada:

#include <immintrin.h>
#include <stdint.h>

__m512i nand512(__m512i a, __m512i b){return ~(a&b);}
__m256i nand256(__m256i a, __m256i b){return ~(a&b);}
__m128i nand128(__m128i a, __m128i b){return ~(a&b);}
uint64_t nand64(uint64_t a, uint64_t b){return ~(a&b);}
uint32_t nand32(uint32_t a, uint32_t b){return ~(a&b);}
uint16_t nand16(uint16_t a, uint16_t b){return ~(a&b);}
uint8_t nand8(uint8_t a, uint8_t b){return ~(a&b);}

Comando para producir la asamblea:

gcc -O3 -c -S  -mavx512f test.c

Ensamblado de salida (acortado):

    .file   "test.c"
nand512:
.LFB4591:
    .cfi_startproc
    vpandq  %zmm1, %zmm0, %zmm0
    vpternlogd  $0xFF, %zmm1, %zmm1, %zmm1
    vpxorq  %zmm1, %zmm0, %zmm0
    ret
    .cfi_endproc
nand256:
.LFB4592:
    .cfi_startproc
    vpand   %ymm1, %ymm0, %ymm0
    vpcmpeqd    %ymm1, %ymm1, %ymm1
    vpxor   %ymm1, %ymm0, %ymm0
    ret
    .cfi_endproc
nand128:
.LFB4593:
    .cfi_startproc
    vpand   %xmm1, %xmm0, %xmm0
    vpcmpeqd    %xmm1, %xmm1, %xmm1
    vpxor   %xmm1, %xmm0, %xmm0
    ret
    .cfi_endproc
nand64:
.LFB4594:
    .cfi_startproc
    movq    %rdi, %rax
    andq    %rsi, %rax
    notq    %rax
    ret
    .cfi_endproc
nand32:
.LFB4595:
    .cfi_startproc
    movl    %edi, %eax
    andl    %esi, %eax
    notl    %eax
    ret
    .cfi_endproc
nand16:
.LFB4596:
    .cfi_startproc
    andl    %esi, %edi
    movl    %edi, %eax
    notl    %eax
    ret
    .cfi_endproc
nand8:
.LFB4597:
    .cfi_startproc
    andl    %esi, %edi
    movl    %edi, %eax
    notl    %eax
    ret
    .cfi_endproc

Como se puede ver, para la sub-64-del tamaño de los tipos de datos, las cosas simplemente son manejadas como longs (de ahí el yl y nol), ya que es el "nativo" bitwidth de mi compilador, como parece.

El hecho de que no hay movs es sólo debido al hecho de que eax es el registro que contiene un valor devuelto por la función. Normalmente, usted acaba de calcular en la edi registro de propósito general para calcular el sobre con el resultado.

Para 64 bits, es el mismo – sólo con "quad" (de ahí tirados q) de las palabras, y rax/rsi en lugar de eax/edi.

Parece que para la 128 bits de los operandos y los más grandes, Intel no le importaba poner en práctica un "no" operación; en su lugar, el compilador produce un all-1 registrarse (auto-comparación del registro con sí mismo, el resultado se almacena en el registro con el vdcmpeqd instrucción), y xors que.

En resumen: Mediante la implementación de una complicada operación con múltiples primaria de instrucciones, que no necesariamente ralentizar funcionamiento – sencillamente, no existe ninguna ventaja en tener una instrucción que hace el trabajo de múltiples instrucciones, si no más rápido.

10voto

Peter Green Puntos 1888

En primer lugar no hay que confundir bit a bit y operaciones lógicas.

Operaciones a nivel de bit se utiliza generalmente para fijar/borrar/activar/bits de comprobación en los campos de bits. Ninguna de estas operaciones requieren la nand ("y no", también conocido como "poco claro" es más útil).

Operaciones lógicas en la mayoría de los lenguajes de programación modernos son evaluados usando corto-circuito de la lógica. Por lo general, una rama de un enfoque basado en la aplicación de ellos es necesario. Incluso cuando el compilador puede determinar que un corto circuito vs evaluación completa no hace ninguna diferencia para el programa de comportamiento, los operandos de las operaciones lógicas no son, generalmente en una forma conveniente para aplicar la expresión mediante el bit a bit asm operaciones.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X