首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针访问有这么昂贵吗?

指针访问有这么昂贵吗?
EN

Stack Overflow用户
提问于 2017-05-10 16:35:46
回答 2查看 100关注 0票数 1

我有一个在DAW (主机软件)中加载的DLL (VST plugin)中调用非常繁重的Process()函数,例如:

代码语言:javascript
复制
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% (这很好)。

现在,如果我稍微把代码改成这样(基本上是递增和赋值):

代码语言:javascript
复制
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):

代码语言:javascript
复制
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;

有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2017-05-10 16:45:25

你可能会认为“指针数组”是最轻量级的容器。但是CPU不是从容器的角度考虑的。它们只是通过指针读写数值。

这里的问题很可能是您知道两个容器不重叠(没有“子容器”)。但是编译器可能不会告诉CPU这一点。写入mBlockStep可能会影响mBlockFraction。编译器没有运行时值,因此它需要处理有运行时值的情况。这将意味着引入更多的内存读取,以及更少的值在寄存器中的缓存。

票数 2
EN

Stack Overflow用户

发布于 2017-05-10 16:57:04

  1. 将所有数据项打包到一个结构中,并创建一个结构数组。我将简单地使用vector.
  2. In Process函数从这个向量中获取单个元素,并使用它的参数。在高速缓存线/指令级,所有项目将被(有效地)带入本地高速缓存(L1),作为连续的数据元素(结构的成员)。使用结构类型的引用或指针以避免复制。除非需要double,否则
  3. 尝试使用整数数据类型。

编辑

代码语言:javascript
复制
struct VoiceInfo 
{ 
   double mValue; 
   ...
}; 
VoiceInfo voices[PLUG_VOICES_BUFFER_SIZE];
// Or vector<VoiceInfo> voices;

..。

代码语言:javascript
复制
void Envelope::Process(Voice &voice) 
{
     // Get the object (by ref/pointer)
     VoiceInfo& info = voices[voice.mIndex];
     // Work with reference 'info'
  ...
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43887384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档