AVX: выравнивание данных: сбой хранилища, хранилище, загрузка, загрузка не
Я модифицирую 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, 0, size);
return memory;
}
и это по крайней мере 50 элементов длиной. (Кстати, с VS2012 у меня есть недопустимая инструкция для некоторого случайного назначения, поэтому я использую linux.)
заранее спасибо, Аркантус.