ฉันต้องการเห็นด้วยกับไบรอันที่นี่และ Wouter และ pjc50
ฉันต้องการเพิ่มให้โดยทั่วไปโดยเฉพาะอย่างยิ่ง CISC ตัวประมวลผลคำสั่งไม่ได้มีปริมาณงานเท่ากัน - การดำเนินการที่ซับซ้อนอาจใช้เวลานานกว่านั้นง่ายกว่า
พิจารณา X86: AND
(ซึ่งเป็นการดำเนินการ "และ") อาจจะเร็วมาก NOT
เดียวกันจะไปสำหรับ ลองดูที่การถอดชิ้นส่วน:
ใส่รหัส:
#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);}
คำสั่งในการผลิตประกอบ:
gcc -O3 -c -S -mavx512f test.c
การชุมนุมเอาท์พุท (สั้นลง):
.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
อย่างที่คุณเห็นสำหรับประเภทข้อมูลขนาด 64- บิตสิ่งต่าง ๆ ล้วนได้รับการจัดการเป็นเวลานาน (เช่น the และlและไม่ใช่l ) เนื่องจากเป็นบิตบิต "ดั้งเดิม" ของคอมไพเลอร์ของฉันอย่างที่เห็น
ความจริงที่ว่ามีmov
ในระหว่างนั้นเป็นเพียงเพราะความจริงที่ว่าการeax
ลงทะเบียนที่มีค่าตอบแทนของฟังก์ชั่น โดยปกติคุณเพียงแค่คำนวณในการedi
ลงทะเบียนทั่วไปเพื่อคำนวณผลลัพธ์
สำหรับ 64 บิตก็เหมือนกัน - เพียงแค่มี "สี่เหลี่ยม" (เพราะฉะนั้นต่อท้ายq
) คำพูดและrax
/ rsi
แทน/eax
edi
ดูเหมือนว่าสำหรับตัวถูกดำเนินการ 128 บิตและใหญ่กว่านั้น Intel ไม่สนใจที่จะใช้การดำเนินการ "ไม่" คอมไพเลอร์สร้าง all- 1
register (เปรียบเทียบตัวเองของ register กับตัวเองส่งผลให้เก็บไว้ใน register ด้วยvdcmpeqd
คำสั่ง) และxor
s นั้น
กล่าวโดยย่อ: ด้วยการใช้งานการดำเนินการที่ซับซ้อนด้วยคำสั่งเบื้องต้นหลายคำคุณไม่จำเป็นต้องชะลอการดำเนินการ - ไม่มีประโยชน์ที่จะมีคำสั่งเดียวที่ทำงานหลายคำสั่งถ้ามันไม่เร็วขึ้น