2015-05-19 79 views
3

我正在修改RNNLM神经网络来研究语言模型。然而,考虑到我的语料库的大小,它运行得很慢。我试图优化矩阵*向量例程(这是对于小数据集总时间的63%负责(我预计它会在更大的集合上更糟糕))。现在我被固有内容困住了。如果我改变AVX:数据对齐:商店崩溃,storeu,加载,loadu不

_mm256_storeu_ps (&(dest.ac[b*8+from+0]), t4); 

(带u未对齐我想)一切都会按计划

_mm256_store_ps (&(dest.ac[b*8+from+0]), t4); 

不过:在

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); 
    } 

这个例子崩溃。我的问题是:为什么加载工作(而不应该,如果数据未对齐)和存储不。 (此外两者都在同一地址上运行)。

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, 0, size); 
    return memory; 
} 

分配和它的至少50个元素长。 (顺便说一句VS2012我有一些随机任务的非法指令,所以我用linux。)

先谢谢了, Arkantus。

+0

'from'的值是什么?是否有'_mm256_load_ps'内在的实际实现为2个128位加载的机会? –

+0

从崩溃时的值是891. &(dest.ac [b * 8 + from + 0])= 0x957e6c 。所以在表格中间有一个访问权限,但这不是对齐的。带有该值的 – Arkantus

+0

更加令人惊讶的是负载起作用。你有没有检查你是否实际加载了正确的值(对于那个值)? –

回答

0

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试了一个小实验,它根本没有生成vmovaps,因为我只用加载的结果作为其他指令的输入。它使用内存操作数生成该指令。 AVX指令对其存储器操作数没有对齐要求。 (穿过缓存线时性能下降,穿越页面边界时击中更大,但代码仍然有效)

另一方面,该存储区确实会生成vmov...指令。由于您使用了对齐所需版本,因此它在未对齐的地址上发生故障。只需使用未对齐的版本;当地址对齐时它会一样快,而当它不对齐时仍然工作。

我没有仔细检查你的代码,看看所有的访问是否应该对齐。我不认为,从你说的话来说,只是问为什么你不会因未对齐的负载而出现故障。就像我说的,可能你的代码只是没有编译成任何vmovaps加载指令,否则即使是“对齐”的AVX加载也不会在未对齐的地址上出错。

你在Sandy/Ivybridge CPU上运行AVX(没有AVX2或FMA?)吗?我假设这就是为什么你的FMA内在评论被注释掉了。

+0

是的,我在Sandy CPU上使用AVX。是的一些访问不对齐!谢谢 !我会使用你的版本,我明白了为什么! – Arkantus