Следующий цикл выполняется сотни раз.
elma and elmc are both unsigned long (64-bit) arrays, so is res1 and res2. </p>
<pre><code>unsigned long simdstore[2];
__m128i *p, simda, simdb, simdc;
p = (__m128i *) simdstore;
for (i = 0; i < _polylen; i++)
{
u1 = (elma[i] >> l) & 15;
u2 = (elmc[i] >> l) & 15;
for (k = 0; k < 20; k++)
{
1. //res1[i + k] ^= _mulpre1[u1][k];
2. //res2[i + k] ^= _mulpre2[u2][k];
3. _mm_prefetch ((const void *) &_mulpre2[u2][k], _MM_HINT_T0);
4. _mm_prefetch ((const void *) &_mulpre1[u1][k], _MM_HINT_T0);
5. simda = _mm_set_epi64x (_mulpre2[u2][k], _mulpre1[u1][k]);
6. _mm_prefetch ((const void *) &res2[i + k], _MM_HINT_T0);
7. _mm_prefetch ((const void *) &res1[i + k], _MM_HINT_T0);
8. simdb = _mm_set_epi64x (res2[i + k], res1[i + k]);
9. simdc = _mm_xor_si128 (simda, simdb);
10. _mm_store_si128 (p, simdc);
11. res1[i + k] = simdstore[0];
12. res2[i + k] = simdstore[1];
}
}
В цикле for скалярная версия кода (с комментариями) выполняется в два раза быстрее, чемкод simd.С выходом cachegrind (чтение инструкций) указанных строк упоминается ниже.
Строка 1: 668,460,000 2 2
Строка 2: 668,460,000 1 1
Строка 3: 89,985,000 1 1
Строка 4: 89,985,000 1 1
Строка 5: 617,040,000 2 2
Строка 6: 44,992,500 0 0
Строка 7: 44,992,500 0 0
Строка 8: 539,910,000 1 1
Строка 9: 128,550,000 0 0
Строка 10:.,.
Строка 11: 205,680,000 0 0
Строка 12: 205,680,000 0 0
Из приведенного выше рисунка видно, что для прокомментированного (скалярного кода) требуется значительно меньшее количество инструкций, чем для кода simd.
Как этот код можно сделать быстрее?