我有一个在DAW (主机软件)中加载的DLL (VST plugin)中调用非常繁重的Process()函数,例如:
for (int i = 0; i < nFrames; i++) {
// ...
for (int voiceIndex = 0; voiceIndex < PLUG_VOICES_BUFFER_SIZE; voiceIndex++) {
Voice &voice = pVoiceManager->mVoices[voiceIndex];
if (voice.mIsPlaying) {
for (int envelopeIndex = 0; envelopeIndex < ENVELOPES_CONTAINER_NUM_ENVELOPE_MANAGER; envelopeIndex++) {
Envelope &envelope = pEnvelopeManager[envelopeIndex]->mEnvelope;
envelope.Process(voice);
}
}
}
}
void Envelope::Process(Voice &voice) {
if (mIsEnabled) {
// update value
mValue[voice.mIndex] = (mBlockStartAmp[voice.mIndex] + (mBlockStep[voice.mIndex] * mBlockFraction[voice.mIndex]));
}
else {
mValue[voice.mIndex] = 0.0;
}
}它基本上占用了主机中CPU的2% (这很好)。
现在,如果我稍微把代码改成这样(基本上是递增和赋值):
void Envelope::Process(Voice &voice) {
if (mIsEnabled) {
// update value
mValue[voice.mIndex] = (mBlockStartAmp[voice.mIndex] + (mBlockStep[voice.mIndex] * mBlockFraction[voice.mIndex]));
// next phase
mBlockStep[voice.mIndex] += mRate;
mStep[voice.mIndex] += mRate;
}
else {
mValue[voice.mIndex] = 0.0;
}
// connectors
mOutputConnector_CV.mPolyValue[voice.mIndex] = mValue[voice.mIndex];
}CPU达到6/7% (请注意,这些变量不会与代码的其他部分交互,至少我是这样认为的)。
我能想到的唯一原因就是对指针的访问太重了?我怎样才能减少这个CPU的数量?
这些数组是基本的双“指针”数组(最轻量级的C++ container):
double mValue[PLUG_VOICES_BUFFER_SIZE];
double mBlockStartAmp[PLUG_VOICES_BUFFER_SIZE];
double mBlockFraction[PLUG_VOICES_BUFFER_SIZE];
double mBlockStep[PLUG_VOICES_BUFFER_SIZE];
double mStep[PLUG_VOICES_BUFFER_SIZE];
OutputConnector mOutputConnector_CV;有什么建议吗?
发布于 2017-05-10 16:45:25
你可能会认为“指针数组”是最轻量级的容器。但是CPU不是从容器的角度考虑的。它们只是通过指针读写数值。
这里的问题很可能是您知道两个容器不重叠(没有“子容器”)。但是编译器可能不会告诉CPU这一点。写入mBlockStep可能会影响mBlockFraction。编译器没有运行时值,因此它需要处理有运行时值的情况。这将意味着引入更多的内存读取,以及更少的值在寄存器中的缓存。
发布于 2017-05-10 16:57:04
vector.Process函数从这个向量中获取单个元素,并使用它的参数。在高速缓存线/指令级,所有项目将被(有效地)带入本地高速缓存(L1),作为连续的数据元素(结构的成员)。使用结构类型的引用或指针以避免复制。除非需要double,否则编辑
struct VoiceInfo
{
double mValue;
...
};
VoiceInfo voices[PLUG_VOICES_BUFFER_SIZE];
// Or vector<VoiceInfo> voices;..。
void Envelope::Process(Voice &voice)
{
// Get the object (by ref/pointer)
VoiceInfo& info = voices[voice.mIndex];
// Work with reference 'info'
...
}https://stackoverflow.com/questions/43887384
复制相似问题