gpt4 book ai didi

c++ - 为什么一个循环比另一个循环需要更长的时间来检测共享内存更新?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:49 26 4
gpt4 key购买 nike

我编写了一个写入共享内存的“服务器”程序,以及一个从内存中读取的客户端程序。服务器有不同的可以写入的“ channel ”,它们也只是附加项目的不同链表。客户端对某些链表感兴趣,并希望读取添加到这些列表中的每个节点,并尽可能减少延迟。

我有两种方法供客户使用:

  1. 对于每个链表,客户端保留一个“书签”指针以保持其在链表中的位置。它轮询链表,一遍又一遍地遍历所有链表(它永远循环),如果可以的话,每次将每个书签向前移动一个节点。它是否可以由节点的“下一个”成员的值决定。如果它是非空的,那么跳转到下一个节点是安全的(服务器自动将它从空切换到非空)。这种方法工作正常,但如果有很多列表要迭代,并且只有少数列表在接收更新,延迟会变得很糟糕。

  2. 服务器为每个列表分配一个唯一的 ID。每次服务器将一个项目附加到列表时,它还会将列表的 ID 号附加到主“更新列表”。客户端只保留一个书签,一个书签进入更新列表。它会不断检查书签的下一个指针是否为非空 (while(node->next_ == NULL) {} ),如果是,则读取给定的 ID,然后处理新节点在具有该 ID 的链表上。从理论上讲,这应该可以更好地处理大量列表,因为客户端不必每次都遍历所有列表。

当我对这两种方法的延迟进行基准测试时(使用 gettimeofday),令我惊讶的是 #2 很糟糕。第一种方法,对于少量链表,延迟通常低于 20us。第二种方法会有少量的低延迟,但通常在 4,000-7,000 微秒之间!

通过在各处插入 gettimeofday,我确定方法 #2 中所有增加的延迟都花在循环中,反复检查下一个指针是否为非空。这让我感到困惑;就好像一个流程中的更改需要更长的时间才能使用第二种方法“发布”到第二个流程。我假设正在进行某种我不理解的缓存交互。怎么回事?

更新:最初,方法 #2 使用条件变量,因此如果 node->next_ == NULL 它将等待条件,并且服务器会在每次发出条件时通知更新。延迟是相同的,并且在试图弄清楚为什么我将代码缩减为上述方法时。我在一台多核机器上运行,所以一个进程自旋锁不应该影响另一个。

更新 2:node->next_ 是易变的。

最佳答案

因为读和写听起来像是发生在不同的 CPU 上,可能是一个 memory barrier有助于?您的写入可能不会在您期望的时候发生。

关于c++ - 为什么一个循环比另一个循环需要更长的时间来检测共享内存更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2524403/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com