Используется ускорение фреймворка, без заметного ускорения
У меня есть следующий фрагмент аудиокода, который я считаю хорошим кандидатом для использования vDSP в рамках ускорения.
// --- get pointers for buffer lists
float* left = (float*)audio->mBuffers[0].mData;
float* right = numChans == 2 ? (float*)audio->mBuffers[1].mData : NULL;
float dLeftAccum = 0.0;
float dRightAccum = 0.0;
float fMix = 0.25; // -12dB HR per note
// --- the frame processing loop
for(UInt32 frame=0; frame<inNumberFrames; ++frame)
{
// --- zero out for each trip through loop
dLeftAccum = 0.0;
dRightAccum = 0.0;
float dLeft = 0.0;
float dRight = 0.0;
// --- synthesize and accumulate each note's sample
for(int i=0; i<MAX_VOICES; i++)
{
// --- render
if(m_pVoiceArray[i])
m_pVoiceArray[i]->doVoice(dLeft, dRight);
// --- accumulate and scale
dLeftAccum += fMix*(float)dLeft;
dRightAccum += fMix*(float)dRight;
}
// --- accumulate in output buffers
// --- mono
left[frame] = (float)dLeftAccum;
// --- stereo
if(right) right[frame] = (float)dRightAccum;
}
// needed???
// mAbsoluteSampleFrame += inNumberFrames;
return noErr;
Таким образом, я изменил его для использования vDSP, умножив fMix на конец блока кадров.
// --- the frame processing loop
for(UInt32 frame=0; frame<inNumberFrames; ++frame)
{
// --- zero out for each trip through loop
dLeftAccum = 0.0;
dRightAccum = 0.0;
float dLeft = 0.0;
float dRight = 0.0;
// --- synthesize and accumulate each note's sample
for(int i=0; i<MAX_VOICES; i++)
{
// --- render
if(m_pVoiceArray[i])
m_pVoiceArray[i]->doVoice(dLeft, dRight);
// --- accumulate and scale
dLeftAccum += (float)dLeft;
dRightAccum += (float)dRight;
}
// --- accumulate in output buffers
// --- mono
left[frame] = (float)dLeftAccum;
// --- stereo
if(right) right[frame] = (float)dRightAccum;
}
vDSP_vsmul(left, 1, &fMix, left, 1, inNumberFrames);
vDSP_vsmul(right, 1, &fMix, right, 1, inNumberFrames);
// needed???
// mAbsoluteSampleFrame += inNumberFrames;
return noErr;
Тем не менее, моя загрузка процессора остается прежней. Я не вижу ощутимой пользы от использования vDSP здесь. Я делаю это правильно? Большое спасибо.
Все еще плохо знакомы с векторными операциями, будь осторожен со мной:)
Если есть какие-то очевидные оптимизации, которые я должен делать (за пределами фреймворка), не стесняйтесь указывать мне это, спасибо!
1 ответ
Ваш векторный вызов выполняет 2 умножения на семпл с частотой дискретизации звука. Если ваша частота дискретизации была 192 кГц, тогда вы говорите только о 384000 умножениях в секунду - этого недостаточно для регистрации на современном процессоре. Более того, вы перемещаете существующие умножения в другое место. Если бы вы взглянули на сгенерированную сборку, я бы предположил, что компилятор оптимизировал ваш исходный код довольно прилично, и любое ускорение вызова vDSP будет компенсировано тем, что вам требуется второй цикл.
Еще одна важная вещь, которую стоит отметить, это то, что все функции vDSP будут работать лучше, когда векторные данные выровнены по 16-байтовой границе. Если вы посмотрите на набор инструкций SSE2 (который, я уверен, vDSP активно использует), вы увидите, что во многих инструкциях есть версия для выровненных данных и другая версия для выровненных данных.
То, как вы бы выровняли данные в gcc, выглядит примерно так:
float inVector[8] = {1, 2, 3, 4, 5, 6, 7, 8} __attribute__ ((aligned(16)));
Или, если вы размещаете в куче, посмотрите, если aligned_malloc
доступен.