Multithreading 同一内核上的线程访问同一缓存线

Multithreading 同一内核上的线程访问同一缓存线,multithreading,caching,optimization,low-level,bare-metal,Multithreading,Caching,Optimization,Low Level,Bare Metal,我在裸机环境中工作,因此在低水平上评估性能。当写入同一缓存线的不同部分时,同一核心上的两个线程应该如何执行 我对多核/多线程体系结构有些陌生。我知道,当不同的内核写入相同的缓存线时,需要锁或原子操作来确保避免竞争条件。同时,在核心之间共享缓存线也会导致性能问题,如错误共享 然而,当两个线程位于同一个内核上时,我是否需要担心类似的事情?我不确定它们是否共享同一个缓存,并且有多个加载存储单元。例如,假设thread1在thread2要写入缓存线的section2的同时写入缓存线的section1。每

我在裸机环境中工作,因此在低水平上评估性能。当写入同一缓存线的不同部分时,同一核心上的两个线程应该如何执行

我对多核/多线程体系结构有些陌生。我知道,当不同的内核写入相同的缓存线时,需要锁或原子操作来确保避免竞争条件。同时,在核心之间共享缓存线也会导致性能问题,如错误共享


然而,当两个线程位于同一个内核上时,我是否需要担心类似的事情?我不确定它们是否共享同一个缓存,并且有多个加载存储单元。例如,假设thread1在thread2要写入缓存线的section2的同时写入缓存线的section1。每个线程是只修改缓存线自己的部分,还是读取整行,修改其部分,然后将整行写回缓存?如果是后者,我需要担心比赛条件或性能延迟吗?

你把事情复杂化了

缓存有不同的层,具体取决于您使用的cpu,不仅是一般的x86或arm,还取决于您使用的体系结构版本/代,但是您可能有一个一级缓存紧密连接到各个内核,然后二级缓存是内核在共享内存/地址空间的过程中聚集在一起的地方

缓存在主内存空间总线上的任何一层上所做的一切都是观察事情的进展,如果事务被标记为可缓存,那么它会检查其标记以查看是否有命中或未命中,并相应地采取行动。缓存不知道,也不知道,也不关心是谁或什么导致了该事务,它是一条指令,是什么指令,该指令来自哪个任务/程序/线程,是预取,是dma引擎。不管怎样,有一个事务和其他任何事务一样遵循规则,如果不可缓存,则将其传递,如果可缓存,则查找命中并处理命中或未命中

因此,如果有多个内核/cpu访问共享缓存,并且由于某种原因,它们访问的内存非常接近,以至于位于同一缓存线中,那么缓存将做出相应的反应


如果你有两个线程的同一个cpu,那么整个cpu在同一时间不适用,当然它也不适用于共享cpu,你可以让它们相隔一个时钟,但它是一个共享总线,在这个级别通常不是双/多端口的。但是,尽管缓存将按照其设计进行操作,如果标记为不可缓存,则忽略并传递,如果标记为不可缓存,则搜索命中,并相应地进行操作。

您希望了解的是,基准测试是b--s--,您不会得到准确的结果,您的结果不仅会因运行而异,尤其是在多核访问共享资源的操作系统上,而且缓存线会一直被逐出,从程序员的角度来看,它看起来是随机的、中断和其他任务,或多或少地移动鼠标,将影响代码在何时运行以及缓存中的内容和不存在的内容,这可能会影响运行之间的性能以及预测性能的尝试。并不是说您不能使用缓存和分支预测器等来评估性能,在这种情况下,您通常不能假设并设计两个线程命中一个缓存线,当发生这种情况时,您希望缓存线位于缓存中,然后再考虑结果的性能。有时很容易使性能变差或变好,比如在引导程序中添加nop,在编译命令行上重新安排对象等等。基准测试和性能评估,没有完全失去它们的价值,但是…谢谢你的回复。我设计的是裸机硬实时,除了在核心之间传递一点数据(这些数据将通过主内存)之外,完全不需要缓存。对于我自己来说,确定的时间,一次又一次的运行,是至关重要的,但你是对的,我可能会忽略这个顺序上的抖动。我更担心丢失数据。我想我的困惑是,我想象线程几乎有一个额外的缓存,大小相当于一条缓存线,它们将对其进行操作并写回。如果它们直接在L1上运行,那么应该没有问题,对吗?取决于处理器,L1是在每个内核中还是共享的?如果每个核心都有自己的缓存,并且每个核心都有一个程序/线程,那么它们就拥有该缓存。然后当它到达共享缓存时,只要其他活动没有将缓存线连接到主内存,不管是谁触摸它,它都在缓存中。这个答案似乎缓存大部分是错误的,甚至没有开始解决关于同一个核心上的线程的实际问题,因为兄弟线程共享所有
提示:编写一个乒乓测试,在两个线程之间来回反弹数据。然后通过超线程将两个线程固定在同一个核心上,并观察计时。感谢您的建议。我试图首先理解期望值,但仅仅运行测试可能是一个可靠的选择。这将在性能延迟方面帮助我。。。我想我也可以做一个竞赛条件测试,将递增的数字写入共享缓存线,看看数据是否与写入的数据不匹配。虽然我不确定这是否会证明这是不可能的,或者只是碰巧没有发生。相关:如果这个问题是关于英特尔与HT的,那么实际上是重复的。你说你有128B缓存线,所以可能没有。您使用的是什么微体系结构?另请参见:@Mystical建议的测试。读/写相同的行可能会导致英特尔硬件上大量内存顺序错误。存储缓冲区在两个超线程之间进行了分区,因此缓存线的错误共享仍然是一个坏问题。@PeterCordes:我正在使用IBM POWER8芯片,因此Power ISA。在本例中,我特别关注SMT2模式,因此是两个线程。cpu手册解释了存储队列在线程之间动态共享,当负载到达队列中的存储时,它们是存储转发的候选对象。也就是说,我知道在SMT2模式下,每个线程都有自己的LSU。然而,我并不清楚每个LSU是否有自己的存储队列,如果有,LSU之间是否允许存储转发。