运行以下简短C代码的编译时出现Segmentation故障:
#include <pmmintrin.h>
#include <stdio.h>
#include <stdlib.h>
#define VALUE 4242
typedef short int Type;
void threshold(Type *dst, const Type *src, int len)
{
short int i, N=16;
short int checkval[] = { VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE };
const short int* __attribute__ ((aligned (16))) line1;
__m128i v1, v2, v3:
v2 = _mm_loadu_si128((__m128i*) checkval );
for(i = 0; i < len; i+=N)
{
line1 = src + N*i;
//Thisline
v1 = _mm_loadu_si128((__m128i*) line1 );
v3 = _mm_cmpgt_epi16( v1, v2 );
_mm_storeu_si128((__m128i*) (dst + N*i), v3 );
}
return;
}
int main()
{
int N = 1024;
Type dst[N], src[N];
int i;
for(i = 0; i < N; i++)
src[i] = rand()%VALUE;
threshold(dst, src, N);
return 0;
}
我很确定“这条线”给我带来问题,但我无法判断问题是否是由于line1不适合__m128i或其他错误引起的。
作为一个子问题 - 我试图对齐line1中的元素,函数_mm_load_si128更合适(我试过两个,但我无法避免这个错误)。
答案 0 :(得分:1)
在threshold
,
short int i, N=16;
应该是:
short int i, N=8;
这是因为每个向量有8个short int
元素,并且指针算法会考虑元素的大小(我的猜测是你假设你需要使用16个字节作为a的大小矢量?)。
答案 1 :(得分:1)
在评论对齐之前,请考虑到houssam的评论和Paul's answer,腐败来自这里肯定。
现在,src
可能不是16字节对齐的。参考此 post about alignment on static arrays,src
至少在2字节字上对齐,但可能不在16字节地址上。
因此,即使将line1
声明为对齐指针,for循环第一行的赋值也可能会破坏此约束。
考虑在__attribute__ ((aligned(8)))
声明中添加src
(main()
内)。
修改强>
在我的评论之后要明确:PaulR在他的回答中指出了一个初始根本原因,类型__m128
的大小为8个短整数而不是16个。另一个失败的根本原因是问题索引i
。通过撰写line1 = src+i*N
和i+=N
,src
的偏移实际上在每次迭代时增加N*N
。
所以你有两个独家解决方案:
i
的增量和索引的结束限制:for(i = 0; i < len/N; i++)
;保持原样。src
和 dst
的偏移 :line1 = src + i;
和_mm_storeu_si128((__m128i*) (dst + i), v3 );