Войти
ПрограммированиеФорумОбщее

C++, низкий уровень, оптимизация быстродействия. (10 стр)

Страницы: 17 8 9 10 11 12 Следующая »
#135
17:32, 17 фев. 2019

Mikle
> Опция /Ob1 есть.
А почему /Ob1, а не /Ob2 https://docs.microsoft.com/en-us/cpp/build/reference/ob-inline-fu… ?view=vs-2017 ?
И вообще, почему не тупо /O2 ?
Ну и для библиотечной memcpy вроде /Oi надо: https://docs.microsoft.com/en-us/cpp/build/reference/oi-generate-… ?view=vs-2017 . Или вручную #pragma intrinsic(memcpy): https://msdn.microsoft.com/en-us/library/tzkfha43.aspx .

#136
(Правка: 18:52) 18:51, 17 фев. 2019

FordPerfect
> Ну и для библиотечной memcpy вроде /Oi надо
Это он только memset инлайнит. То, что memcpy здесь для борьбы с алиасингом, он не понимает.
У меня не получилось на godbolt-е заставить его генерировать нормальный код, как у gcc/clang-а.

#137
19:28, 17 фев. 2019

}:+()___ [Smile]
Оно не то, чтобы совсем не инлайнит:
https://godbolt.org/z/77p5BN
Но эффективность хреновая, да.

#138
(Правка: 19:41) 19:38, 17 фев. 2019

FordPerfect
> Оно не то, чтобы совсем не инлайнит
Оно именно, что только инлайнит.
Берет код memcpy и тупо подставляет, совершенно не пытаясь ничего оптимизировать.
Т. е. оно не видит, что переменная(reg1)⟶memcpy⟶переменная(reg2) можно оптимизировать до reg1⟶reg2, а делает reg1⟶память⟶memcpy⟶память⟶reg2.

#139
(Правка: 21:10) 21:08, 17 фев. 2019

А почему бы не использовать

union
?

Запросто можно получить доступ к элементам x64 переменной в виде byte , word или x64 ...

Или я ошибаюсь ?

Да, придётся модифицировать код. Но, по-моему автор этим и занимается.

#140
21:44, 17 фев. 2019

bykabak
union сможет работать с регистром? Что-то сомневаюсь, как бы это не подвигло компилятор всё переносить в память.

#141
22:02, 17 фев. 2019

Так вопрос же как грузить, а не как значение обрабатывать. Чем union поможет?

Mikle
> union сможет работать с регистром?
Отчасти.
https://godbolt.org/z/I6GHPO

#142
(Правка: 22:27) 22:25, 17 фев. 2019

FordPerfect,

Mikle,
Имеются 2D ARGB спрайты (массивы), с некоторыми частями спрайтов нужно поканально (ARGB каналы) проводить простейшие математические операции, например, сумма, полусумма, произведение (с делением на 256) и т. п.

Я что-то не так понял ?

Куда грузить ?

ASM недоступен же уже из С++.  Всё нужно в регистрах процессора делать ?

#143
22:40, 17 фев. 2019

bykabak
> Я что-то не так понял ?
Всё верно. Но самые медленные операции в этом те, которые работают с памятью, причём чтение четырёх байт отдельно будет гораздо сильнее тормозить, чем чтение их разом в один четырёхбайтовый регистр. Но к частям регистра далеко не всегда есть простой доступ, как к элементам юниона. Скажем, в EAX два младших байта ещё доступны, как AL и AH, а вот два старших никак, только выделять их с помощью битовых операций и сдвигов.
bykabak
> ASM недоступен же уже из С++.
Ну и что? Компилятор то всё равно компилирует в те же инструкции, и желательно представлять, что компилятору будет легко, а что нет.
Кроме того, ASM полудоступен в виде интринсиков, изучением чего я в первую очередь и занимаюсь в этой теме.

#144
(Правка: 23:36) 23:31, 17 фев. 2019

Mikle,

У тебя переменные всё равно в памяти хранятся , а не в регистрах.

union MyUnion
{
  MyUnion () {};

  XMFLOAT4 Fl4;          // SIMD
  unsigned char  B[16];  // Bytes
  unsigned short W[8];   // Words

};


Так разве неудобно достукиваться к данным по байтам и как угодно ?


Ты хочешь грузить x64 переменную в регистр, и потом работать с её частью, а не всей переменной ?  И всё это в регистрах ?

#145
23:43, 17 фев. 2019

bykabak
Операции с памятью всегда существенно медленнее работы с регистрами. Современные процы в десятки сотни раз быстрее памяти.

#146
(Правка: 23:52) 23:46, 17 фев. 2019

Truthfinder,
Я всё это знаю.  Есть ещё кэш на CPU :)

Вот же всё есть

XMBYTE4
XMCOLOR

#147
23:55, 17 фев. 2019

bykabak
> Есть ещё кэш на CPU :)
Мы читаем, умножаем, пишем и забываем в текущих примерах функций. Да и обращение в кэш это 2-3 ns. То есть несколько тактов процессора.

#148
(Правка: 0:18) 0:17, 18 фев. 2019

bykabak
> Я что-то не так понял ?
Интриники вполне неплохо подходят для "с некоторыми частями спрайтов нужно поканально (ARGB каналы) проводить простейшие математические операции".

> Куда грузить ?
Из памяти в SIMD-регистры.

> У тебя переменные всё равно в памяти хранятся , а не в регистрах.
С чего бы это? Переменные вполне могут храниться чисто в регистрах и в память вообще не попадать (если речь о локальных переменных).

> Так разве неудобно достукиваться к данным по байтам и как угодно ?
Можно (если на undefined behavior забить), но особой потребности нет. Т. к. интринсики прекрасно делают то, что нужно.
Ну вот действительно - где предлагается в этом коде применять union?

Truthfinder
> Да и обращение в кэш это 2-3 ns.
Там depends. Обычно говорят, что доступ в L1 кеш имеет 0..4 такта latency.

Mikle
Дело же не только в том, что доступ в память медленный, а что побайтовые операции - над одним байтом, а SSE - над 16.
Причём здесь union к SIMD vs. bytes непонятно (побайтовый доступ можно и без всякого union).

#149
(Правка: 1:28) 1:23, 18 фев. 2019

bykabak
> ASM недоступен же уже из С++.  Всё нужно в регистрах процессора делать ?
провел компиляцию. потом подключаешь дизассемблер дизассемблировать в язык ассемблера.дизассемблируется в язык ассемблера.потом подключаешь ассемблер--и в добрый путь,вперёд и с песней.

Страницы: 17 8 9 10 11 12 Следующая »
ПрограммированиеФорумОбщее