Я пытаюсь собрать 64-битные целые числа из памяти, используя инструкцию ассемблера. Ниже вы можете увидеть, как я вызываю assembly
код из C
. Обратите внимание, что ассемблерный код использует синтаксис NASM
.
nasm_gather.asm
файл
bits 64
section .text
global nasm_gather:function
extern base_addr
extern vindex
nasm_gather:
; prolog
push rbp
push rbx
push r12
push r13
mov r12 ,[rel base_addr] ; r12 point to base_addr
mov r13 ,[rel vindex] ; r13 points to vindex
vmovdqu32 zmm1 ,[r13] ; zmm1 = [2, 5, 1, 3, 0, 4, 7, 6]
vpxorq zmm2 ,zmm2 ,zmm2 ; zmm2 = [0, 0, 0, 0, 0, 0, 0, 0]
vpgatherqq zmm2 ,[r12 + zmm1*8] ; ----> Illegal instruction at address = ...
...
; epilog
pop r13
pop r12
pop rbx
pop rbp
ret
main.cpp
файл
#include <iostream>
#include <immintrin.h>
using namespace std;
extern "C" int nasm_gather();
const int N=32;
int64_t* base_addr /*__attribute__ ((aligned (64)))*/ = (int64_t *) malloc(sizeof(int64_t) * N);
int64_t* vindex = (int64_t *) malloc(sizeof(int64_t) * 8);
int main() {
/* initialize indices */
vindex[0]=2; vindex[1]=5; vindex[2]=1; vindex[3]=3;
vindex[4]=0; vindex[5]=4; vindex[6]=7; vindex[7]=6;
// ...
int64_t result = nasm_gather();
...
return 0;
}
(vpgatherqq zmm, vm64z
ассемблерная инструкция соответствует _mm512_i64gather_epi64 встроенная функция в C)
Как только программа достигает этой точки:
vpgatherqq zmm2 ,[r12 + zmm1*8]
Я получаю ошибку «Недопустимая инструкция»:
Недопустимая инструкция по адресу = 4011f0: 62 d2 fd 48 91 14 cc 62 f1 7e 48 6f c2 e8 10
Если вы считаете, что ваше приложение должно попытаться выполнить эту недопустимую инструкцию (и другие, которые могут присутствовать), то используйте это ручка: -emit-illegal-insts 0 и этого сообщения об ошибке можно избежать.
В чем проблема?
mov r12, [rel base_addr]
загрузитr12
со значением изbase_addr[0]
, тогда как я думаю, вы просто хотите, чтобы оно содержало адресbase_addr
. Поэтому я думаю, что вместо этого вы хотитеlea r12, [rel base_addr]
. Аналогично для следующей строки. Хотя я все равно ожидаю ошибки сегментации вместо недопустимой инструкции. - person Nate Eldredge   schedule 01.05.2021Illegal instruction at address = 4011dc: 62 d2 fd 48 91 14 cc 62 f1 7e 48 6f c2 e8 07
- person him   schedule 01.05.2021gcc -O2 -march=skylake-avx512 -masm=intel
). Кроме того, на uops.info будет пример синтаксиса сборки именно того, что было протестировано. - person Peter Cordes   schedule 01.05.2021vpgatherqq
из C, используйте_mm512_mask_i64gather_epi64
изimmintrin.h
. software.intel.com/sites/landingpage/IntrinsicsGuide/. И не используйте глобальные переменные для передачи аргументов! Я надеюсь, вы на самом деле не планируете использовать это для производительности. - person Peter Cordes   schedule 01.05.2021kxnorw k1 ,k0 ,k0
// k1 = 255vpgatherqq zmm2{k1} ,[r12 + zmm1*8]
Но я получаю такое же сообщение об ошибке. - person him   schedule 01.05.2021-fno-pie -no-pie -mavx512f
- person him   schedule 01.05.2021-mavx512f
для этого кода или immintrin.h, потому что вы не используете__m512i
. Шаг GCC C-asm не видит ничего SIMD, только вызов функции. (Так что это ужасно для эффективности.) - person Peter Cordes   schedule 01.05.2021kxnorb k, k, k
, но проблема остается прежней - person him   schedule 01.05.2021vmovdqu32
,kxnorb
)? - person him   schedule 01.05.2021...
) - person chtz   schedule 02.05.2021sde64 -icl -- ./main
- person him   schedule 02.05.2021