加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 并行计算内存访问瓶颈

发布时间:2020-12-16 03:37:52 所属栏目:百科 来源:网络整理
导读:以下算法在我的程序中迭代运行.没有下面指出的两条线,运行它只需要1.5倍.这对我来说非常令人惊讶.然而,更糟糕的是,使用这两行运行会使完成运行增加4.4倍(6.6X不运行整个算法).另外,它导致我的程序无法扩展到超过~8个核心.事实上,当在单核上运行时,这两条线只
以下算法在我的程序中迭代运行.没有下面指出的两条线,运行它只需要1.5倍.这对我来说非常令人惊讶.然而,更糟糕的是,使用这两行运行会使完成运行增加4.4倍(6.6X不运行整个算法).另外,它导致我的程序无法扩展到超过~8个核心.事实上,当在单核上运行时,这两条线只会将时间增加到1.7倍,考虑到它们的作用,这仍然太高.我已经排除它与我程序中其他地方的修改数据的影响有关.

所以我想知道是什么原因引起的.可能与缓存有关吗?

void NetClass::Age_Increment(vector <synapse> & synapses,int k)  
{
    int size = synapses.size();
    int target = -1;

    if(k > -1)
    {
        for(int q=0,x=0 ; q < size; q++)
        {
            if(synapses[q].active)
                synapses[q].age++;
            else
            {
                if(x==k)target=q;
                x++;
            }
        }
        /////////////////////////////////////Causing Bottleneck/////////////
        synapses[target].active = true;
        synapses[target].weight = .04 + (float (rand_r(seedp) % 17) / 100);
        ////////////////////////////////////////////////////////////////////
    }

    else
    {
        for(int q=0 ; q < size; q++)
            if(synapses[q].active)
                synapses[q].age++;
    }
}

更新:将两个问题行更改为:

bool x = true;
float y = .04 + (float (rand_r(seedp) % 17) / 100);

删除问题.建议可能与内存访问有关吗?

解决方法

每个线程修改内存读取的所有其他读取:
for(int q=0,x=0 ; q < size; q++)
   if(synapses[q].active) ... // ALL threads read EVERY synapse.active
...
synapses[target].active = true; // EVERY thread writes at leas one synapse.active

这些来自不同线程的同一地址的读写会导致大量的缓存失效,这将导致您描述的症状.解决方案是避免在循环内部写入,并且将写入移动到局部变量的事实再次证明问题是缓存失效.请注意,即使您不写正在阅读的理智字段(活动),您也可能会因错误共享而看到相同的症状,因为我怀疑活动,年龄和体重共享缓存行.

有关详细信息,请参阅CPU Caches and Why You Care

最后要注意的是,对活动和重量的分配,更不用说年龄增量似乎都非常不安全.此类更新的互锁操作或锁定/互斥保护是强制性的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读