Я сделал тест с этимКогда программа выиграет от предварительной загрузки и невременной загрузки/хранения?
for (i32 i = 0; i < 0x800000; ++i)
{
// Hopefully this can disable hardware prefetch
i32 k = (i * 997 & 0x7FFFFF) * 0x40;
_mm_prefetch(data + ((i + 1) * 997 & 0x7FFFFF) * 0x40, _MM_HINT_NTA);
for (i32 j = 0; j < 0x40; j += 0x10)
{
//__m128 v = _mm_castsi128_ps(_mm_stream_load_si128((__m128i *)(data + k + j)));
__m128 v = _mm_load_ps((float *)(data + k + j));
a_single_chain_computation
//_mm_stream_ps((float *)(data2 + k + j), v);
_mm_store_ps((float *)(data2 + k + j), v);
}
}
Результаты странные.
- Независимо от того, сколько времени занимает
a_single_chain_computation
, латентность нагрузки не скрыта. - И, кроме того, дополнительное суммарное время увеличивается, когда я добавляю больше вычислений. (С одним
v = _mm_mul_ps(v, v)
предварительная выборка сохраняет около 0,60 - 0,57 = 0,03 с. И с 16v = _mm_mul_ps(v, v)
она экономит около 1,1 - 0,75 = 0,35 с. ПОЧЕМУ?) - Невременная загрузка/хранение ухудшает производительность с предварительной выборкой или без нее. (Я понимаю, часть нагрузки, но почему магазины тоже?)
Вы пробовали обычную предварительную выборку? По моему опыту, у меня никогда не было хорошего варианта использования для невременных нагрузок. Но я обнаружил, что потоковые хранилища полезны при выполнении абсолютно случайных записей в идеально выровненных блоках размера кешины. – Mysticial
@Mysticial '_MM_HINT_NTA' описывается как« минимизация загрязнения кэша », предполагая, что он не является временным. Но _MM_HINT_Tx, похоже, не ухудшает производительность. Угадайте, потому что нет другого использования кеша. – BlueWanderer
Я бы не ожидал, что '_MM_HINT_Tx' ухудшит производительность. В случае невременной предварительной выборки, кажется, саморазрушится, чтобы предварительно извлечь что-то и не загрязнять кеш. Поскольку цель предварительной выборки - это привести ее в кеш. Это одна из вещей, которые я действительно никогда не понимал. :) – Mysticial