从内存加载向量的更好方法. (铛)

我正在编写一个测试程序来习惯Clang对OpenCL样式向量的语言扩展.我可以让代码工作,但我遇到了问题的一个方面.我似乎无法弄清楚如何让clang只是很好地加载来自标量数组的向量.

目前我必须做一些事情:

byte16 va = (byte16){ argv[1][start],argv[1][start + 1],argv[1][start + 2],argv[1][start + 3],argv[1][start + 4],argv[1][start + 5],argv[1][start + 6],argv[1][start + 7],argv[1][start + 8],argv[1][start + 9],argv[1][start + 10],argv[1][start + 11],argv[1][start + 12],argv[1][start + 13],argv[1][start + 14],argv[1][start + 15]};

我最好喜欢这样的事情:

byte16 va = *(byte16 *)(&(argv[1][start]));

我可以轻松地使用适用于ARM或x86的内在函数.但是该代码会导致程序崩溃,尽管它会编译.

解决方法

在x86上发生崩溃的原因之一是由于对齐问题.我没有在我的系统上使用clang来重现问题,但我可以在GCC的例子中证明这一点.

如果您执行以下操作:

/* Define a vector type of 16 characters.  */
typedef char __attribute__ ((vector_size (16))) byte16;

/* Global pointer.  */
char *  foo;

byte16 test ()
{
  return *(byte16 *)&foo[1];
}

现在如果你在支持向量的x86上编译它:

$ gcc -O3 -march=native -mtune=native   a.c

您将获得以下程序集进行测试:

test:
    movq foo(%rip),%rax
    vmovdqa 1(%rax),%xmm0
    ret

请注意,此举是一致的,这当然是错误的.现在,如果你将这个函数内联到main中,你会得到类似的东西:

int main ()
{
  foo = __builtin_malloc (22);
  byte16 x = *(byte16 *)&foo[1];
  return x[0];
}

你会没事的,你会得到不对齐的指示.这是一种错误,它在编译器中没有很好的修复,因为它需要通过添加新数据结构等进行过程间优化.

问题的根源是编译器假定向量类型是对齐的,因此当您取消引用对齐的向量类型数组时,可以使用对齐的移动.作为GCC中问题的解决方法,可以定义一个未对齐的向量类型,如:

typedef char __attribute__ ((vector_size (16),aligned (1))) unaligned_byte16;

并使用它来取消引用未对齐的内存.

我不确定您是否在设置中遇到了这个问题,但我建议通过检查编译器的汇编输出来检查.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...