![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| ANTON_AL |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 292 Регистрация: 27.1.2007 Репутация: нет Всего: нет |
Доброго дня!
Есть у меня проект, в котором реализована поддержка SSE2. Есть возможность выбора типа вычислений - с SSE2 и без него. В результате получается, то приложение с SSE2 работает в 3 раза медленнее, чем без него. Пытаюсь включить оптимизацию, при сборке пишет
. . .что это за параметры такие? Добавлено через 8 минут и 30 секунд Смотрел MSDN, там просто список значений параметров компилятора. Можно ссылочку на какую нибудь статью про оптимизацию компилятором. |
|||
|
||||
| ANTON_AL |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 292 Регистрация: 27.1.2007 Репутация: нет Всего: нет |
Мне удалось включить оптимизацию по скорости, я нашел, что такое RTC1. . .
Но оптимизация не дала никакого эффекта, хотя я влкючил и раскрытие inline функций любой вложенности, и favor fast code и всё, что как то может повлиять на скорость. Может надо как то хитро настроить компилятор. . . |
|||
|
||||
| neondartal |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 25.11.2009 Репутация: нет Всего: нет |
Тут все зависит от того - как ты используешь SSE2 - в своем коде - имеет значение струтура данных и ее выравнивание
Вот смотри - этот код чисто использует xmm регистры - скорость в несколько раз быстрее но надо правильно их использовать - почитай MSDN (Intrinsic functions) - сами функции - можно не испльзовать - главное использовать правильные струтуры - типа этой, чтобы компилятор - автоматически смог подставить инструкции SSE2. Для SSE можно определять массив структур AoS и структуру массивов SoA - это сильно влияет на скорость. __declspec(align(32)) struct vec { public: vec():x1(0),x2(0),x3(0),x4(0){}; vec(float _x1, float _x2, float _x3, float _x4):x1(_x1),x2(_x2),x3(_x3),x4(_x4){}; __forceinline vec & operator+ (const vec &vec2) { this->x1 += vec2.x1; this->x2 += vec2.x2; this->x3 += vec2.x3; this->x4 += vec2.x4; return *this; } float x1,x2,x3,x4; }; vec z[1000] - массив струтур AoS struct SOA { __declspec(align(32)) float a1[1000]; __declspec(align(32)) float a2[1000]; __declspec(align(32)) float a3[1000]; __declspec(align(32)) float a4[1000]; } SoA и AoS - используются по разному - и код может быть медленным независимо от SSE2 int _tmain(int argc, _TCHAR* argv[]) { vec v1(1.0f,2.3f,4.5f,6.7f); vec v2(1.3f,2.5f,4.6f,3.7f); vec v4 = v1 + v2; v4 = v4 + v1; wprintf_s(L"%f %f %f %f \n",v4.x1, v4.x2, v4.x3, v4.x4); return 0; } Посмотри - это код дизасемблера - то что нужно. Но этот код может быть не будет именно супербыстрым (но с FPU не сравнить) - так как слишком много ненужных команд. убери из кода второе сложение - и хоть умри - компилить будет для FPU(для одного такого сложения - будет - быстрее FPU и компилер это видит) - чтобы от этого избавиться (именно от такого варинта) - надо либу на ASM вручную грузить в регистры значения и производить мат. операции - либо использовать библиотечные функции из "emmintrin.h" (SSE2) и "mmintrin.h" (SSE). Тут есть "косяк" - слишком много кода - скорее из-за конструктора копирования. Но это просто пример. vec v1(1.0f,2.3f,4.5f,6.7f); vec v2(1.3f,2.5f,4.6f,3.7f); vec v4 = v1 + v2; 00401009 movss xmm0,dword ptr [__real@40133333 (402140h)] v4 = v4 + v1; wprintf_s(L"%f %f %f %f \n",v4.x1, v4.x2, v4.x3, v4.x4); 00401011 fld qword ptr [__real@4012666660000000 (402138h)] 00401017 movss dword ptr [esp],xmm0 0040101C movss xmm0,dword ptr [__real@4099999a (402130h)] 00401024 movss dword ptr [esp+4],xmm0 0040102A movss xmm0,dword ptr [__real@4111999a (40212Ch)] 00401032 movss dword ptr [esp+8],xmm0 00401038 movss xmm0,dword ptr [__real@41266666 (402128h)] 00401040 movss dword ptr [esp+0Ch],xmm0 00401046 movq xmm0,mmword ptr [esp] 0040104B movq mmword ptr [esp+20h],xmm0 00401051 movq xmm0,mmword ptr [esp+8] 00401057 movq mmword ptr [esp+28h],xmm0 0040105D movq xmm0,mmword ptr [esp+10h] 00401063 movss xmm2,dword ptr [esp+2Ch] 00401069 movss xmm1,dword ptr [esp+28h] 0040106F movq mmword ptr [esp+30h],xmm0 00401075 movq xmm0,mmword ptr [esp+18h] 0040107B movq mmword ptr [esp+38h],xmm0 00401081 movss xmm0,dword ptr [esp+24h] 00401087 cvtps2pd xmm2,xmm2 0040108A addsd xmm2,mmword ptr [__real@4024ccccc0000000 (402120h)] 00401092 cvtps2pd xmm1,xmm1 00401095 addsd xmm1,mmword ptr [__real@4022333340000000 (402118h)] 0040109D sub esp,20h 004010A0 cvtps2pd xmm0,xmm0 004010A3 addsd xmm0,mmword ptr [__real@4013333340000000 (402110h)] 004010AB cvtpd2ps xmm2,xmm2 004010AF cvtpd2ps xmm1,xmm1 004010B3 cvtss2sd xmm2,xmm2 004010B7 movsd mmword ptr [esp+18h],xmm2 004010BD cvtpd2ps xmm0,xmm0 004010C1 cvtss2sd xmm1,xmm1 004010C5 movsd mmword ptr [esp+10h],xmm1 004010CB cvtss2sd xmm0,xmm0 004010CF movsd mmword ptr [esp+8],xmm0 004010D5 fstp qword ptr [esp] 004010D8 push offset string L"%f %f %f %f \n" (4020F4h) 004010DD call dword ptr [__imp__wprintf_s (40209Ch)] 004010E3 add esp,24h А вот код для одного сложения(FPU) - насколько меньше инструкций. Для SSE2 - желательно - как можно меньше производить загрузку и выгрузку из памяти в регистры xmm - это занимает время. vec v1(1.0f,2.3f,4.5f,6.7f); vec v2(1.3f,2.5f,4.6f,3.7f); vec v4 = v1 + v2; // v4 = v4 + v1; wprintf_s(L"%f %f %f %f \n",v4.x1, v4.x2, v4.x3, v4.x4); 00401006 fld qword ptr [__real@4024ccccc0000000 (402128h)] 0040100C sub esp,20h 0040100F fstp qword ptr [esp+18h] 00401013 fld qword ptr [__real@4022333340000000 (402120h)] 00401019 fstp qword ptr [esp+10h] 0040101D fld qword ptr [__real@4013333340000000 (402118h)] 00401023 fstp qword ptr [esp+8] 00401027 fld qword ptr [__real@4002666660000000 (402110h)] 0040102D fstp qword ptr [esp] 00401030 push offset string L"%f %f %f %f \n" (4020F4h) 00401035 call dword ptr [__imp__wprintf_s (40209Ch)] 0040103B add esp,24h А вот код сложения на ASM z[] = (x0+y0, x1+y1, x2+y2, x3+y3) Это "быстрый" код __asm { movaps xmm0,x addps xmm0, y movaps z, xmm0 } Command line error D8016 : '/O2' and '/RTC1' command-line options are incompatible cl Maximize Speed (/O2) и Both (/RTC1, equiv. to /RTCsu)(проверка на ошибки во время исполнения) - не используются вместе - убери вообще проверку Runtime Check - из Release Build. Ссылку дать не могу - хватило MSDN и cтарой статейки Ламота из "Прог-ие 3д игр" - кратко и по теме. Но это книга. Не эл. вариант. Сорри. Сама по себе оптимизация компилером - и так производится всегда - особой разницы наяву не заметно - кроме (SSE2). Стандартный Release Build - делает и так все возможное. Оптимизация компилером ничтожно мала по сравнению с оптимизацией логики алгоритма - на себе убедился - да и слова - не мои Это сообщение отредактировал(а) neondartal - 4.12.2009, 08:30 |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
SSE2 сам по себе не очень эффективен. Рекомендуется использовать что нибудь поновее (SSE3, SSSE3, SSE4.1)
|
|||
|
||||
| neondartal |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 25.11.2009 Репутация: нет Всего: нет |
"SSE2 сам по себе не очень эффективен. Рекомендуется использовать что нибудь поновее (SSE3, SSSE3, SSE4.1)"
C таким успехом можно сказать что SSE3 будет неэффективен через 2 года. Насчет увеличения скорости раз в 5 - я сказал - вполне реально сделанная оптимизация в проге. А то какой процессор стоит - не играет роли - не знаешь как оптимизировать для SSE - руками или нет - тогда не знаешь также и про SSE2 SSE3 ... - принцип - один и тотже - подстраивание структур данных под компилятор+SSEN или письмо руками. Если сравнить SSE2 с FPU - то оно круче последнего, разве не так ?? |
|||
|
||||
| xvr |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Не будет. АППАРАТНАЯ реализация SSE2 получилось несколько кривая. То же самое на SSE3 и 4.1 получается быстрее (на десятки процентов). У Intel'а был проект по динамической оптимизации кода (на этапе исполнения), в частности одной из оптимизаций было удаление из кода инструкций ИМЕННО SSE2 и замена их на SSE4.1
Intel'овский компилятор умеет генерить код с использованием всех SSE (сколько бы их там не было) Это сообщение отредактировал(а) xvr - 5.12.2009, 11:58 |
||||||
|
|||||||
| neondartal |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 25.11.2009 Репутация: нет Всего: нет |
Конечно Intel компилер и MS - несравнимы. Да и то, что я показал - будет выходить только под MS - под Intel компиляцию - выйдет намного качественней - чего я не уточнил сразу. Со всем согласен - смотря со стороны вашей мысли
|
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |