gpt4 book ai didi

assembly - `vpbroadcastd' 的操作数类型不匹配

转载 作者:行者123 更新时间:2023-12-01 15:02:22 25 4
gpt4 key购买 nike

我试图找到 Xeon Phi 平台的 KNC 广播指令。但是我找不到任何说明。相反,我尝试在汇编中使用这个 AVX _mm512_set1_epi32 内在函数。我有两个问题:第一,有没有KNC广播指令?其次,当我编译下面的代码时,我得到了'vpbroadcastd'错误的操作数类型不匹配。

int op = 2;
__asm__("vmovdqa32 %0,%%zmm0\n\t"
"mov %1, %%eax\n\t"
"vpbroadcastd %%eax, %%zmm1\n\t"
"vpsravd %%zmm1,%%zmm0,%%zmm1\n\t"
"vmovdqa32 %%zmm1,%0;"
: "=m" (tt[0]): "m" (op));

其中 tt 使用下面的代码定义,我使用 k1om-mpss-linux-gcc 编译器编译这段代码

int * tt = (int *) aligned_malloc(16 * sizeof(int),64);

最佳答案

我查看了 AVX2 如何使用内在函数执行此操作,并注意到广播从内存中读取,就像使用 KNC 一样。从 AVX2 内部函数看汇编,我编写了内联汇编,它做同样的事情。

#include <stdio.h>
#include <x86intrin.h>
void foo(int *A, int n) {
__m256i a16 = _mm256_loadu_si256((__m256i*)A);
__m256i t = _mm256_set1_epi32(n);
__m256i s16 = _mm256_srav_epi32(a16,t);
_mm256_storeu_si256((__m256i*)A, s16);
}

void foo2(int *A, int n) {
__asm__("vmovdqu (%0),%%ymm0\n"
"vpbroadcastd (%1), %%ymm1\n"
"vpsravd %%ymm1, %%ymm0, %%ymm0\n"
"vmovdqu %%ymm0, (%0)"
:
: "r" (A), "r" (&n)
: "memory"
);
}

int main(void) {
int x[8];
for(int i=0; i<8; i++) x[i] = 1<<i;
for(int i=0; i<8; i++) printf("%8d ", x[i]); puts("");
foo2(x,2);
for(int i=0; i<8; i++) printf("%8d ", x[i]); puts("");
}

这是我对 KNC 的猜测(使用对齐负载):

void foo2_KNC(int *A, int n) {
__asm__("vmovdqa32 (%0),%%zmm0\n"
"vpbroadcastd (%1), %%zmm1\n"
"vpsravd %%zmm1, %%zmm0, %%zmm0\n"
"vmovdqa32 %%zmm0, (%0)"
:
: "r" (A), "r" (&n)
: "memory"
);
}

使用 KNC 和 AVX512 似乎有一种更有效的方法。

Intel says关于“2.5.3 广播”部分中的 AVX12:

EVEX encoding provides a bit-field to encode data broadcast for some load-op instructions

然后举个例子

vmulps zmm1, zmm2, [rax] {1to16}

在哪里

The {1to16} primitive loads one float32 (single precision) elem ent from memory, replicates it 16 times to form a vector of 16 32-bit floating-point elements, multiplies the 16 float32 elements with the corresponding elements in the first source operand vector, and put each of the 16 results into the destination operand.

我以前从未使用过他的语法,但你可以试试

void foo2_KNC(int *A, int n) {
__asm__("vmovdqa32 (%0),%%zmm0\n\t"
"vpsravd (%1)%{1to16}, %%zmm0, %%zmm0\n\t"
"vmovdqa32 %%zmm0, (%0)\t"
:
: "r" (A), "r" (&n)
: "memory", "%zmm0"
);

这产生

vmovdqa32      (%rax),%zmm0
vpsravd (%rdx){1to16}, %zmm0, %zmm0
vmovdqa32 %zmm0, (%rax)

Agner Fog 在 the documentation for objconv 中有一个标题为“AVX-512 和 Knights Corner 指令的 8.4 汇编语法”的部分。他说的地方

these two instruction sets are very similar, but have different optional instruction attributes. Instructions from these two instruction sets differ by a single bit in the prefix, even for otherwise identical instructions.

根据他的文档,NASM 支持 AVX-512 和 KNC 语法,因此您可以在 NASM 中尝试这种语法。

关于assembly - `vpbroadcastd' 的操作数类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34374341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com