Моя (simd) реализация занимает разное количество времени, хотя она запускается для фиксированного ввода. Время работы варьируется от, скажем, 100 миллионов тактовых циклов до 120 миллионов тактовых циклов. Программа вызывает функцию около 600 раз, и самая затратная часть функции находится в памяти, доступ к которой осуществляется ~2000 раз. Таким образом, общее использование памяти в моей программе довольно велико.
Не связано ли изменение времени работы с моделями доступа к памяти/начальным содержимым памяти?
Я использовал valgrind для анализа профиля моей программы. Это показывает, что каждый доступ к памяти занимает около 8 инструкций. Это нормально?
Ниже приведен фрагмент кода (функция), который вызывается 600 раз. Mulprev[32][20] — это массив, к которому обращаются чаще всего.
j = 15;
u3v = _mm_set_epi64x (0xF, 0xF);
while (j + 1)
{
l = j << 2;
for (i = 0; i < 20; i++)
{
val1v = _mm_load_si128 ((__m128i *) &elm1v[i]);
uv = _mm_and_si128 (_mm_srli_epi64 (val1v, l), u3v);
u1 = _mm_extract_epi16 (uv, 0);
u2 = _mm_extract_epi16 (uv, 4) + 16;
for (ival = i, ival1 = i + 1, k = 0; k < 20; k += 2, ival += 2, ival1 += 2)
{
temp11v = _mm_load_si128 ((__m128i *) &mulprev[u1][k]);
temp12v = _mm_load_si128 ((__m128i *) &mulprev[u2][k]);
val1v = _mm_load_si128 ((__m128i *) &res[ival]);
val2v = _mm_load_si128 ((__m128i *) &res[ival1]);
bv = _mm_xor_si128 (val1v, _mm_unpacklo_epi64 (temp11v, temp12v));
av = _mm_xor_si128 (val2v, _mm_unpackhi_epi64 (temp11v, temp12v));
_mm_store_si128 ((__m128i *) &res[ival], bv);
_mm_store_si128 ((__m128i *) &res[ival1], av);
}
}
if (j == 0)
break;
val0v = _mm_setzero_si128 ();
for (i = 0; i < 40; i++)
{
testv = _mm_load_si128 ((__m128i *) &res[i]);
val1v = _mm_srli_epi64 (testv, 60);
val2v = _mm_xor_si128 (val0v, _mm_slli_epi64 (testv, 4));
_mm_store_si128 (&res[i], val2v);
val0v = val1v;
}
j--;
}
Я хочу сократить время вычислений моей программы. Какие-либо предложения?