Временные хранилища частей упакованного двойного вектора с использованием SSE / AVX - PullRequest
3 голосов
/ 10 декабря 2011

Это совмещение по предыдущему вопросу , который у меня был относительно разнесения отдельных элементов вектора __m256d в разные области памяти (операция разброса).Мой код хранит много данных в памяти, к которым не обращаются в течение "долгого времени".Я хотел бы уменьшить количество кеш-памяти, создаваемой всеми этими магазинами, используя не временные инструкции.Тем не менее, я не могу придумать хороший способ сделать это.Вот краткое изложение того, как мой код выглядит сейчас:

__m256d src = ...  //  data
double *dst;
int dst_dist;

__m128d a = _mm256_extractf128_pd(src, 0);
__m128d b = _mm256_extractf128_pd(src, 1);

_mm_storel_pd(dst + 0*dst_dist, a);
_mm_storeh_pd(dst + 1*dst_dist, a);
_mm_storel_pd(dst + 2*dst_dist, b);
_mm_storeh_pd(dst + 3*dst_dist, b);

Я хотел бы выполнить 64-битные хранилища, используя временную подсказку, но, похоже, нет способа сделать этонепосредственно из регистра XMM.Как лучше всего это сделать?

Ответы [ 2 ]

4 голосов
/ 10 декабря 2011

Есть веская причина избегать использования хранилищ частичных регистров с невременной подсказкой. Если вы попытаетесь разбросать множество небольших фрагментов данных по совершенно не связанным областям памяти, переполнение буфера, объединяющее процессорные записи, и вы получите обычную запись через кэши (возможно, с дополнительными затратами производительности).

Правильный способ использовать комбинирование записи (не временная подсказка) - заполнить всю строку кэша. Поэтому обычно объединяют части данных в полный регистр, а затем записывают его сразу с помощью MOVNTDQ.

2 голосов
/ 10 декабря 2011

Вы можете сохранить части вектора SSE с временным указанием, используя инструкцию MASKMOVDQU.Семантика не отображается точно на ваш пример, но ее можно заставить работать.Однако эту инструкцию обычно следует использовать только для того, чтобы избежать ветвления (даже тогда, как правило, лучше использовать выбор и обычное хранилище).Это также просто немного громоздко в использовании, так как адрес для сохранения неявно указан в инструкции.

Операция, которую вы выполняете, очень похожа на фрагмент транспонирования матрицы (или 90 градусов)поворот изображения).Сохраняете ли вы другие данные по соседним адресам?Есть ли какой-нибудь способ, которым вы можете изменить свой алгоритм для пакетирования этих хранилищ и записи полных векторов вместо этого (возможно, даже используя непрерывную запись в небольшой кешируемый буфер с нуля и выполняя некоторое комбинирование записи в программном обеспечении)?

...