¿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?.
Respuestas
¿Demasiados anuncios?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.
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.
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.
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 mov
s 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 xor
s 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.
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.