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

Помогите оптимизировать код

Страницы: 1 2 3 4 5 6 Следующая »
#0
18:09, 3 июня 2015

Оптимизирую свой синтезатор музыки.
Профайлер говорит, что 15% времени процессора занимает этот код:

for(uint i=0; i<numSamples; i++)
{
  *dst=(short)(*src * 32767);
  dst++; src++;
}
Здесь массив порядка 10000 - 100000 float семплов музыки конвертируется в short для воспроизведения. Семплы уже находятся в интервале [-1, 1]. Понятно, что приведение float к int - тормозная операция, но может можно что-то придумать, чтобы её ускорить? Вариант, перевести всё на инты, не предлагать.

Правка: Это уже не актуально, актуальные вопросы ближе к концу темы.


#1
18:23, 3 июня 2015

Мне кажется этот цикл можно распараллелить.

#2
18:30, 3 июня 2015

Digan
> Мне кажется этот цикл можно распараллелить.
Распараллелить можно, но я хочу уложиться в один поток. Другие потоки и так есть чем загрузить, поэтому нагрузку это не уменьшит. А вот если тут можно использовать SIMD, тогда другое дело. Вот только я никогда не использовал SSE и не знаю, как его использовать. Хотелось бы обойтись intrinsic'ами, без ассемблера.

#3
18:46, 3 июня 2015

думаю все получится на основе этой доки + _mm_cvtps_pi16

#4
19:46, 3 июня 2015

gammaker
Как минимум можно избавиться от лишних инкрементов:

const float* end = src + numSamples;

while (src < end)
{
   *dst = (short)(*src * 32767);
   ++dst, ++src;
}
большого буста не даст, но все равно приятно )
#5
20:01, 3 июня 2015

baga
> думаю все получится на основе этой доки + _mm_cvtps_pi16
Получилось. Прирост не очень большой, но теперь профайлер ругается на другие куски кода. Буду их тоже на SSE переписывать.

#6
20:27, 3 июня 2015

GCC, если ему сказать, что можно SSE2, вроде сам его использует, и сам его параллелит (O3).

options    ns/sample
---------------------
FPU, O0     27.7
FPU, O2     13.7
FPU, O3     13.8
SSE2, O0    9.2
SSE2, O2    4.1
SSE2, O3    2.9
( https://ideone.com/8c2OPv )

Вот дизасм (возможно, другая версия GCC)
O2: https://goo.gl/tyCNh2 - скалярные операции
O3: https://goo.gl/tdRzMr - видно параллельный блок и скалярный хвостик для некратных размеров.

#7
20:39, 3 июня 2015

FordPerfect
> GCC, если ему сказать, что можно SSE2, вроде сам его использует, и сам его
> параллелит (O3).
В студии тоже можно включить SSE\SSE2\AVX, но я замечал, что с ним иногда даже производительность ниже, да и размер exe увеличивается. К тому же из-за хаков, которые я использую, чтобы отвязаться от CRT, в студии проект с включённым SSE не компилируется.
Поэтому лучше руками, так надёжнее.

#8
20:41, 3 июня 2015

А нельзя ли float генерировать в пределах [-32767..32767], чтобы избежать умножения в этом цикле?

#9
20:46, 3 июня 2015

Впрочем старомодный http://kunaifusu.livejournal.com/221098.html , вроде, заруливает оба (результаты чуть разные):
https://ideone.com/I4rkWT

#10
20:57, 3 июня 2015

Sergio
> А нельзя ли float генерировать в пределах [-32767..32767], чтобы избежать
> умножения в этом цикле?
Действительно, оказалось, что у меня был цикл, в котором было сложение и умножение. Я просто поменял множитель в нём и этот цикл упростился просто до каста к short, который я сделал через _mm_cvtps_pi16.
По идее через AVX таким образом можно сразу по 8 семплов обрабатывать? Там есть соответствующая инструкция?

FordPerfect
> Впрочем старомодный http://kunaifusu.livejournal.com/221098.html , вроде,
> заруливает оба (результаты чуть разные):
> https://ideone.com/I4rkWT
А _mm_cvtps_pi16 зарулит?

#11
21:06, 3 июня 2015

На всякий случай: код из #9 множит на 32768, а не 32767. И для +1.0f, видимо, будет бяка.

#12
21:10, 3 июня 2015

FordPerfect
> На всякий случай: код из #9 множит на 32768, а не 32767. И для +1.0f, видимо,
> будет бяка.
А если допустим у меня уже интервал [-32767; 32767], то этот метод можно адаптировать?

#13
21:20, 3 июня 2015

gammaker
Да, вроде:
https://ideone.com/gXu0oG

#14
21:34, 3 июня 2015

FordPerfect
> Да, вроде:
> https://ideone.com/gXu0oG
Прикольно. А на каких платформах кроме x86 это работает?

Страницы: 1 2 3 4 5 6 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.