c – AVX:数据对齐:存储崩溃,storeu,load,loadu没有
我正在修改RNNLM神经网络来研究语言模型.但是考虑到我的语料库的大小,它的运行速度非常慢.我试图优化矩阵*向量例程(对于小数据集,这是一个对总时间的63%负责的例子(我希望它在较大的集合上更糟)).现在我陷入了内在的困境.
for (b=0; b<(to-from)/8; b++) { val = _mm256_setzero_ps(); for (a=from2; a<to2; a++) { t1 = _mm256_set1_ps (srcvec.ac[a]); t2 = _mm256_load_ps(&(srcmatrix[a+(b*8+from+0)*matrix_width].weight)); //val =_mm256_fmadd_ps (t1,t2,t3) t3 = _mm256_mul_ps(t1,t2); val = _mm256_add_ps (val,t3); } t4 = _mm256_load_ps(&(dest.ac[b*8+from+0])); t4 = _mm256_add_ps(t4,val); _mm256_store_ps (&(dest.ac[b*8+from+0]),t4); } 此示例崩溃: _mm256_store_ps (&(dest.ac[b*8+from+0]),t4); 但是,如果我改为 _mm256_storeu_ps (&(dest.ac[b*8+from+0]),t4); (我认为,对于未对齐而言)一切都按预期工作.我的问题是:为什么加载工作(如果数据未对齐则不应该加载)而商店不加载. (此外,两者都在同一地址上运行). dest.ac已经使用分配 void *_aligned_calloc(size_t nelem,size_t elsize,size_t alignment=64) { size_t max_size = (size_t)-1; // Watch out for overflow if(elsize == 0 || nelem >= max_size/elsize) return NULL; size_t size = nelem * elsize; void *memory = _mm_malloc(size+64,alignment); if(memory != NULL) memset(memory,size); return memory; } 它至少有50个元素. 先感谢您, 解决方法
TL:DR:在优化代码中,loads will fold into memory operands for other operations,which don’t have alignment requirements in AVX.商店不会.
您的示例代码本身无法编译,因此我无法轻松检查_mm256_load_ps编译的指令. 我尝试了一个使用gcc 4.9的小实验,并且它根本没有为_mm256_load_ps生成vmovaps,因为我只使用了load的结果作为另一条指令的输入.它使用内存操作数生成该指令. AVX指令对其内存操作数没有对齐要求. (跨越缓存行会有性能损失,跨越页面边界会有更大的影响,但您的代码仍然有效.) 另一方面,商店确实生成了vmov …指令.由于您使用了对齐所需的版本,因此它在未对齐的地址上出现故障.只需使用未对齐版本;当地址对齐时它会一样快,而当它没有时它仍然可以工作. 我没有仔细检查你的代码,看看是否应该对齐所有的访问.我假设没有,从你用它的方式来解释为什么你也没有因未对齐的载荷而出错.就像我说的,可能你的代码只是没有编译到任何vmovaps加载指令,否则即使“对齐”AVX加载也不会在未对齐的地址上出错. 你在Sandy / Ivybridge CPU上运行AVX(没有AVX2或FMA吗?)?我认为这就是为什么你的FMA instrinsics被注释掉了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |