Каково максимальное теоретическое ускорение благодаря SSE для простого двоичного вычитания?

StackOverflow https://stackoverflow.com/questions/1466907

Вопрос

Пытаясь выяснить, сталкивается ли внутренний цикл моего кода с барьером аппаратного проектирования или с барьером непонимания с моей стороны.Это еще немного не все, но самый простой вопрос, на который я могу ответить, заключается в следующем:

Если у меня есть следующий код:

float px[32768],py[32768],pz[32768];
float xref, yref, zref, deltax, deltay, deltaz;

initialize_with_random(px);
initialize_with_random(py);
initialize_with_random(pz);

for(i=0;i<32768-1;i++) {
  xref=px[i];
  yref=py[i];
  zref=pz[i];
  for(j=0;j<32768-1;j++ {
    deltx=xref-px[j];
    delty=yref-py[j];
    deltz=zref-pz[j];
  } }

Какое максимальное теоретическое ускорение я мог бы увидеть, перейдя к инструкциям SSE в ситуации, когда у меня есть полный контроль над кодом (сборка, встроенные компоненты, что угодно), но нет контроля над средой выполнения, отличной от архитектуры (т. Е.это многопользовательская среда, поэтому я ничего не могу поделать с тем, как ядро ОС назначает время моему конкретному процессу).

Прямо сейчас я вижу увеличение скорости в 3 раза с моим кодом, когда я бы подумал, что использование SSE даст мне гораздо большую векторную глубину, чем указывает увеличение скорости в 3 раза (предположительно, увеличение скорости в 3 раза говорит мне, что у меня максимальная теоретическая пропускная способность в 4 раза).(Я пробовал такие вещи, как разрешение deltx / delty / deltz быть массивами на случай, если компилятор недостаточно умен, чтобы автоматически продвигать их, но я по-прежнему вижу ускорение только в 3 раза.) Я использую компилятор intel C с соответствующими флагами компилятора для векторизации, но, очевидно, никаких встроенных функций.

Это было полезно?

Решение

Это зависит от процессора.Но теоретический максимум не превысит 4x.Я не знаю ни одного процессора, который мог бы выполнять более одной команды SSE за такт, а это значит, что он может самое большее вычислите 4 значения за цикл.

Большинство процессоров могут это делать по крайней мере одна скалярная команда с плавающей запятой за цикл, так что в этом случае вы увидите теоретическое максимальное ускорение в 4 раза.

Но вам придется посмотреть конкретную пропускную способность команд для процессора, на котором вы работаете.

Однако практическое ускорение в 3 раза - это довольно хорошо.

Другие советы

Я думаю, вам, вероятно, придется каким-то образом чередовать внутренний цикл.3-Компонентный вектор выполняется одновременно, но это всего лишь 3 операции одновременно.Чтобы добраться до 4, вы должны сделать 3 компонента из первого вектора и 1 из следующего, затем 2 и 2, и так далее.Если вы создали какую-то очередь, которая загружает и обрабатывает данные 4 компонентов одновременно, а затем разделяете их после, это может сработать.

Редактировать:Вы могли бы развернуть внутренний цикл, чтобы выполнять 4 вектора за итерацию (предполагая, что размер массива всегда кратен 4).Это позволило бы выполнить то, о чем я сказал выше.

Рассмотреть:Какой ширины поплавок?Насколько широка инструкция SSEx?Это соотношение должно давать вам какую-то разумную верхнюю границу.

Также стоит отметить, что вышедшие из строя трубы мешают получить хорошие оценки ускорения.

Вам следует подумать укладка петлевой плитки - способ, которым вы получаете доступ к значениям во внутреннем цикле, вероятно, вызывает много сбоев в кэше данных L1.Это не так уж плохо, потому что все, вероятно, по-прежнему помещается в L2 объемом 384 КБ, но между попаданием в кэш L1 и попаданием в кэш L2 разница на порядок, так что это может иметь большое значение для вас.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top