C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Оптимизация загрузки конвееров процессора, Оптимизация загрузки конвееров процессор
vvkot
Отправлено: 23.11.2006, 08:55


Ученик-кочегар

Группа: Участник
Сообщений: 20



Кто подскажет в каких случаях процессор сбрасывает конвееры в которых он делает предвыборку команд? Слышал, что вроде при операциях ветвления. Всегда-ли. Для чего нужно: есть код с четверной вложенностью циклов:(размерность первого цикла 1000, второго 100, третьего 20, четвертого самого внутреннего 10000). Внутри всех этих циклов крутится очень короткий код всего три оператора: суммирование (накопление суммы), сравнение с суммы с число, при положительном результате суммирование (накопление другой суммы).
Код тяжеловат получается, как бы ускорить: почитал на эту тему, есть варианты типа организовывать шаг внутреннего цикла через один и накапливать две суммы (типа, чтобы в кэш помещалось), а что еще можно предприянть, чтобы ускорится? Переменные где суммируем регичтровыми сделать, а может как нибудь ММХ (SSE) команды применить можно.

Отредактировано vvkot — 23.11.2006, 08:58
Grigoriy
Отправлено: 23.11.2006, 18:00


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE
...в каких случаях процессор сбрасывает конвееры в которых он делает предвыборку команд?

Микропроцессор сбрасывает конвейеры в случае, если изменяется содержимое хотя бы одного из регистров CS:eip и если новые значения в этих регистрах не соответствуют предсказываемым значениям, получаемым блоком предсказания меток перехода, являющимся одним из устройств микропроцессора.
QUOTE
Переменные где суммируем регичтровыми сделать, а может как нибудь ММХ (SSE) команды применить можно.

Регистровыми.
SSEN-команды применить можно в большинстве случаев, в определенных случаях скорость выполнения увеличивается в 4...8 раз.

А вам знакомы SSE-инструкции ?
Дело в том, что я думаю, что если вам они знакомы и вам полностью понятен код программы, о котором вы пишете, то скорее всего вы бы не задавали этот вопрос... wink.gif
Хотите сами использовать SSE, SSE2 — тогда ознакомьтесь с их использованием.

Отредактировано Grigoriy — 23.11.2006, 18:02
vvkot
Отправлено: 24.11.2006, 00:03


Ученик-кочегар

Группа: Участник
Сообщений: 20



Grigoriy, я смотрю Вы не понаслышке слышали про SSE, не подскажете в чем может быть ошибка в этом коде (выдает ошибку при загрузке массива b в mmx1, а также при выгрузке из него):


float a[4]= {2,3,4,5};
float b[4]= {5,6,7,8};
float c[4];

__asm {
mov edx,a
movaps xmm0, [edx]
mov edx,b
movaps xmm1, [edx]
addps xmm1,xmm0
mov edx,c
movaps [edx], xmm1
}

Grigoriy
Отправлено: 24.11.2006, 00:57


Мастер участка

Группа: Участник
Сообщений: 381



И этот код будет с вероятностью 25% выдавать ошибку !
В данном случае он не совсем корректный. Почему...

Потому что для всех арифметико-логических (но не для инструкций пересылки!) инструкций XMM 128-битный операнд обязательно должен быть выровнен в памяти на границу параграфа (параграф=16 байт).
Это означает, что 4 младших бита значения физического адреса 128-битного операнда должны равняться 0 (нулевой, первый, второй и третий биты физического адреса должны быть равны 0). Физический же адрес накладывается на адресную шину процессора, которая является частью системной шины процессора. Особенность работы инструкций XMM-расширения такова по причине того, что разработчики архитектуры компьютеров стремяться упростить архитектуру и сделать ее максимально быстродействующей.
И так. Известно, что сегмент данных в адресном пространстве выровнен тоже, более того, он выровнен даже не на 16 байт, а возможно на страницу памяти (4096 байт). Остается только выровнять смещение, а оно является значением указателя. Посмотрите функцию GlobalAlloc, как она выделяет блок памяти... выровненный на 8 байт. Нужно дополнительно проверять на кратность указатель, и если он не кратен 16 байтам — применить адресную переменную, указывающую на 8 байт дальше...

Для инструкций пересылки...
MOVAPS — требует выравнивания на 16 байт операнда.
MOVUPS — не требует выравнивания, но выполняется медленнее.
MOVHPS rxmm, m64 и MOVHPS m64, rxmm — перемещают старшие 64 бита между регистром и памятью и не требует выравнивания.
MOVLPS rxmm, m64 и MOVHPS m64, rxmm — перемещают младшие 64 бита между регистром и памятью и не требует выравнивания.
MOVSS rxmm, m32 и MOVSS rxmm, rxmm и MOVSS m32, rxmm — перемещает только младшее 32 битное число и не требует выравнивания. Если приемником является XMM-регистр — старшие 3 операнда устанавливаются в 0.

Для невыровненных массивов
CODE

float a[4]= {2,3,4,5};
float b[4]= {5,6,7,8};
float c[4];

__asm {
mov edx,a
movups xmm0, [edx]
mov edx,b
movups xmm1, [edx]
addps xmm1,xmm0
mov edx,c
movups [edx], xmm1
}

А для выровненных wink.gif
CODE

float a[4]= {2,3,4,5};
float b[4]= {5,6,7,8};
float c[4];

__asm {
mov edx,a
movaps xmm0, [edx]
addps xmm0, [edx+16]
movaps [edx+32], xmm0
}
vvkot
Отправлено: 24.11.2006, 01:05


Ученик-кочегар

Группа: Участник
Сообщений: 20



Про требование о выравнивании данных я читал, и даже пробовал, но ошибка та же самая и в том же месте, т.е. movups не помогает. Может что то я в принципе не так делаю: я создал пустой проект (в CB6), кинул на форму батон, и по клику на батон пытаюсь выполнить приведенный выше код.

Отредактировано vvkot — 24.11.2006, 01:08
Grigoriy
Отправлено: 24.11.2006, 02:04


Мастер участка

Группа: Участник
Сообщений: 381



Компилятор асма Билдера построен так, что идентификатор массива он воспринимает не так как смещение массива в памяти, а как первый его элемент. Команда LEA должна использоваться, чтобы занести смещение массива.
Работает...
CODE

float a[4]= {2,3,4,5};
float b[4]= {5,6,7,8};
float c[4];

__asm {
lea edx,a
movups xmm0, [edx]
lea edx,b
movups xmm1, [edx]
addps xmm1,xmm0
lea edx,c
movups [edx], xmm1
}      
vvkot
Отправлено: 24.11.2006, 08:38


Ученик-кочегар

Группа: Участник
Сообщений: 20



И правда работает.... Благодарю незнамо как... Жаль пока еще по интернету нельзя пиво отпралять, а то непременно бы воспользовался таким сервисом
Gedeon
Отправлено: 27.11.2006, 12:32


Ветеран

Группа: Модератор
Сообщений: 1742



QUOTE (vvkot @ 24.11.2006, 08:38)
Жаль пока еще по интернету нельзя пиво отпралять, а то непременно бы воспользовался таким сервисом

Это самый большой недостаток интернета.

Вернуться в Вопросы программирования в C++Builder