gpt4 book ai didi

c - `vmovaps' 的段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:07 26 4
gpt4 key购买 nike

我在 Xeon Phi 英特尔协处理器上使用 KNC 指令和(512 位长 vector )编写了一个代码来添加两个数组。但是,我在内联汇编部分中有分段部分。

这是我的代码:

int main(int argc, char* argv[])
{
int i;
const int length = 65536;
const int AVXLength = length / 16;
float *A = (float*) aligned_malloc(length * sizeof(float), 64);
float *B = (float*) aligned_malloc(length * sizeof(float), 64);
float *C = (float*) aligned_malloc(length * sizeof(float), 64);
for(i=0; i<length; i++){
A[i] = 1;
B[i] = 2;
}

float * pA = A;
float * pB = B;
float * pC = C;
for(i=0; i<AVXLength; i++ ){
__asm__("vmovaps %1,%%zmm0\n"
"vmovaps %2,%%zmm1\n"
"vaddps %%zmm0,%%zmm0,%%zmm1\n"
"vmovaps %%zmm0,%0;"
: "=m" (pC) : "m" (pA), "m" (pB));

pA += 512;
pB += 512;
pC += 512;
}
return 0;
}

我正在使用 gcc 作为编译器(因为我没有钱购买 intel 编译器)。这是我编译此代码的命令行:

k1om-mpss-linux-gcc add.c -o add.out

问题在内联汇编中。以下内联汇编修复了它。

__asm__("vmovaps %1,%%zmm1\n"
"vmovaps %2,%%zmm2\n"
"vaddps %%zmm1,%%zmm2,%%zmm3\n"
"vmovaps %%zmm3,%0;"
: "=m" (*pC) : "m" (*pA), "m" (*pB));

最佳答案

作为already explained , 骑士角 (KNC) 没有 AVX512。但是,它确实有类似的东西。 事实证明,KNC vs AVX512 问题在这里是一个转移注意力的问题。问题出在 OPs 内联汇编中。

我建议您使用内部函数而不是使用内联汇编。 KNC 内在函数在 Intel Intrinsic Guide online 中进行了描述.

此外,Przemysław Karpiński at CERN extend Agner Fog's Vector Class Library to use KNC .您可以找到 git 存储库 here .如果您查看文件 vectorf512_mic.h您可以学到很多关于 KNC 内在函数的知识。

我将您的代码转换为使用这些内在函数(在本例中与 AVX512 内在函数相同):

int main(int argc, char* argv[])
{
int i;
const int length = 65536;
const int AVXLength = length /16;
float *A = (float*) aligned_malloc(length * sizeof(float), 64);
float *B = (float*) aligned_malloc(length * sizeof(float), 64);
float *C = (float*) aligned_malloc(length * sizeof(float), 64);
for(i=0; i<length; i++){
A[i] = 1;
B[i] = 2;
}
for(i=0; i<AVXLength; i++ ){
__m512 a16 = _mm512_load_ps(&A[16*i]);
__m512 b16 = _mm512_load_ps(&B[16*i]);
__m512 s16 = _mm512_add_ps(a16,b16);
_mm512_store_ps(&C[16*i], s16);
}
return 0;
}

只有 ICC 支持 KNC 内部函数。但是,KNC 带有 Manycore Platform Software Stack (MCSS)它带有一个特殊版本的 gcc,k1om-mpss-linux-gcc,它可以使用 AVX512,例如使用内联汇编的 KNC 功能。


在这种情况下,KNC 和 AVX512 的助记符相同。因此我们可以使用 AVX512 内在函数来发现要使用的程序集

void foo(int *A, int *B, int *C) {
__m512i a16 = _mm512_load_epi32(A);
__m512i b16 = _mm512_load_epi32(B);
__m512i s16 = _mm512_add_epi32(a16,b16);
_mm512_store_epi32(C, s16);
}

gcc -O3 -mavx512 knc.c产生

vmovaps (%rdi), %zmm0
vaddps (%rsi), %zmm0, %zmm0
vmovaps %zmm0, (%rdx)

从这个使用内联汇编的解决方案将是

__asm__("vmovaps   (%1), %%zmm0\n"
"vpaddps (%2), %%zmm0, %%zmm0\n"
"vmovaps %%zmm0, (%0)"
:
: "r" (pC), "r" (pA), "r" (pB)
:
);

使用前面的代码,GCC 为每个数组生成添加指令。这是一个更好的解决方案,它使用仅生成一个加法的索引寄存器。

for(i=0; i<length; i+=16){
__asm__ __volatile__ (
"vmovaps (%1,%3,4), %%zmm0\n"
"vpaddps (%2,%3,4), %%zmm0, %%zmm0\n"
"vmovaps %%zmm0, (%0,%3,4)"
:
: "r" (C), "r" (A), "r" (B), "r" (i)
: "memory"
);
}

最新版本的 MPSS (3.6) 包括支持 AVX512 内在函数的 GCC 5.1.1。因此,我认为您可以在 AVX512 内在函数与 KNC 内在函数相同时使用它们,并且仅在它们不一致时才使用内联汇编。查看 Intel Intrinsic 指南表明它们在大多数情况下是相同的。

关于c - `vmovaps' 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34148636/

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