- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
共享内存多处理系统通常需要为缓存一致性生成大量流量。核心 A 写入缓存。 Core B 稍后可能会读取相同的内存位置。因此,内核 A,即使它本来可以避免写入主内存,也需要向内核 B 发送通知,告诉 B 如果该地址正在缓存中,则该地址无效。
究竟什么时候需要这样做,这是一个复杂的问题。不同的 CPU 架构有不同的内存模型,这里上下文中的内存模型是一组关于观察到的事情发生的顺序的保证。内存模型越弱,A 在发送通知的确切时间就越放松对于 B,A 和 B 更容易并行做更多的事情。不同 CPU 架构的内存模型总结:https://en.wikipedia.org/wiki/Memory_ordering#Runtime_memory_ordering
所有的讨论似乎都是关于失效发生的时间,事情发生的顺序。
但在我看来,在许多工作负载中,A 写入的大部分数据永远不会被 B 使用,因此如果可以完全消除那些缓存失效的总线流量会更好。专用于执行缓存一致性的硬件仍然需要存在,因为 A 和 B 有时需要共享数据,但是写入共享总线是 CPU 可以做的更耗能的事情之一,并且电池生命周期和散热通常是现在限制资源,因此减少总线流量将是一个有用的优化。有没有办法做到这一点?
从效率的角度来看,理想的情况是如果忽略总线流量是默认的(因为大多数写入的数据不与其他线程共享),并且您必须在需要缓存一致性的地方显式地发出内存屏障。另一方面,这可能是不可能的,因为假设它在 x86 或 ARM 上运行的现有代码量很大;有没有办法反过来,向 CPU 指示给定的缓存行永远不会对任何其他线程感兴趣?
我会对任何系统的答案感兴趣,但最特别是 x64、ARM 或 RISC-V 上 Linux 最常见的当前/ future 服务器配置。
最佳答案
真正的 CPU 不使用共享总线;流量通过一个 L3 缓存,它的标签用作监听过滤器(特别是在单插槽 Intel 芯片中)。或在其他微架构上节省流量的类似方法。您是对的,当您扩展到多个内核时,实际上向每个其他内核广播消息的功耗和性能成本会高得令人望而却步。 共享总线只是像 MESI 这样的协议(protocol)的简单思维模型,而不是现代 CPU 中的真正实现。 见 What cache coherence solution do modern x86 CPUs use?例如。
带有写分配的回写缓存需要在您存储到缓存行之前读取缓存行,因此它们具有该行其他部分的原始数据。这种读取,当由写入触发时,称为“所有权读取”(RFO),以使线路进入 MESI 独占状态(可以在没有外部流量的情况下转换为脏修改)。 RFO 包括失效。
如果初始访问是只读的,如果没有其他内核具有缓存副本 ,则该行通常会像 RFO 一样以独占状态到达(即它在 L3(最后一级)缓存中丢失)。这意味着对于读取一些私有(private)数据然后修改它的常见模式,流量保持在最低水平。
我认为,多 socket 系统必须监听另一个 socket 或咨询监听过滤器来确定这一点,但对功率/能量最敏感的系统是移动的(总是单 socket )。
有趣的事实:Skylake-X 之前的 Intel 2-socket Xeon 芯片(例如 E5 ...-v4)没有用于套接字之间流量的监听过滤器,并且只是在 QPI 链路上的另一个套接字上进行垃圾邮件监听。 E7 CPU(能够在四核和更大的系统中使用)具有专用的监听过滤器缓存来跟踪热线的状态,以及足够的 QPI 链接来交叉连接更多的插槽。来源:John McCalpin's post on an Intel forum ,虽然我还没有找到太多其他数据。也许约翰在考虑像 Core2/Nehalem Xeons 这样的早期系统,英特尔确实在其中谈到了具有监听过滤器的功能,例如
https://www.intel.ca/content/dam/doc/white-paper/quick-path-interconnect-introduction-paper.pdf将 QPI 与其早期设置进行比较。并且有一些关于可以权衡延迟与吞吐量的监听模式的更多细节。也许英特尔只是没有以同样的方式使用术语“窥探过滤器”。
Is there a way to do it the other way around, to indicate to the CPU that a given cache line will never be of interest to any other thread?
rep stos
/
rep movs
)甚至在 ERMSB 也可以使用无 RFO 写入协议(protocol)(
at least in P6, according to Andy Glew who designed it )之前,即使它们将数据留在缓存中等级制度。但是,这仍然需要使其他缓存失效,除非该内核已经拥有处于 E 或 M 状态的线路。
Enhanced REP MOVSB for memcpy
mmap(PROT_WRITE|PROT_READ, MAP_SHARED)
。)
clflush
或
clwb
强制写回外部缓存。)
mmap(MAP_SHARED)
.因此,您不能默认将堆栈空间映射为非连贯或类似的东西,并且编译程序以使用额外的刷新指令,以防它们获得指向确实需要可见的非连贯内存的指针,毕竟这将完全失败整个事情的目的。
关于multithreading - 减少缓存行失效的总线流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62614838/
目录 总线是什么? 常见总线类型有哪些? 总线的串行和并行的区别? 数据总线 地址总线
从下面的代码我在 map 上添加标记,每 15 秒刷新一次并从数据库中获取新的纬度和经度。标记(巴士图像)已成功添加到 map 上并从一个位置平稳移动到另一个位置,就像汽车在路上行驶一样。现在我想要的
如果在小端处理器上运行的程序将未缓存的值 0xaabbccdd 写入地址 0,并且处理器使用 32 位宽的 AXI4 总线,那么 WDATA 的第 31-24 位是 0xaa 还是 0xdd? AXI
是否存在用于将进程内服务消息传递给另一个服务的扭曲机制?我写了一个原型(prototype)总线,看起来像 from collections import defaultdict ch
我修改了设备树文件并使用 4 个 GPIO 引脚启用了 spi,这些引脚支持 pinmux 并从 gpio 切换到 spi 功能。但是在 Linux 内核代码中,代码如何知道使用了哪个 spi 总线/
我正在使用控创嵌入式计算机通过 I2C 与 ST 微 Controller 通信。我正在使用开发适配器与 I2C 接口(interface),使用描述的简单 read() 和 write() 函数 h
我有一个需要 PEC 的 I2C/SMBus 设备我正在为它编写一个内核空间驱动程序。 在 Linux 2.6.37 上我使用 i2c_board_info实例化客户端并在那里设置标志,但现在驱动程序
我想确认我的消息已经通过 socketCAN 库保存在 CAN 总线上。socketCAN 文档描述了使用 recvmsg() 函数时的这种可能性,我对其实现有疑问。 我要实现的功能是确认我的消息在仲
下面是我的代码 #import #import int main(int argc, const char *argv[]) { char *str = "First string";
在大量使用 D-Bus 的应用程序中获得更好的时间性能有哪些好的做法? ? 以下是我们的团队通过硬敲学校学到的一些知识: 尝试将数据实体组合成一个单一的大型结构/对象,以通过 D-Bus IPC 发送
我正在Akka内核下运行Akka应用程序,该程序在其他系统上也可以正常工作。 akka { loggers = ["akka.event.slf4j.Slf4jLogger"] log
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
我是 C 语言新手,对于家庭作业考试,我必须实现一个简单的服务器套接字程序,该程序在循环中发送一些数据,并且如果客户端连接到服务器套接字(已使用 Arduino 完成,但需要相同的功能)在 raspb
我正在构建一个由许多(> 100)个相同节点组成的系统,所有节点均通过 CAN 总线连接。这个想法是所有节点必须具有相同的信息,任何节点都可以生成事件并通过 CAN 广播它。对于这些事件,CAN 帧提
您好,我在解析 IIB Toolkit 中的任何 JSON 时遇到问题。 java计算节点抛出的异常为:java.lang.NoClassDefFoundError: org.json.JSONObj
我买了这个传感器: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Weather/RHT03.pdf 输出为“MaxDetect 1-w
我正在用户空间编写包装器 API,用于在嵌入式 Linux 平台上用 C 语言控制 I2C 总线。我能够使用 read() 和 write() 方法以及 ioctl() 调用来选择从属设备,从而从传感
在我的软件(用 C++ 编写)中,我使用 Linux 标准函数打开 CAN 总线套接字并执行 I/O 操作。 套接字的打开和使用如下: /* Create the socket */ if ((
每天——大约 5 到 10 次——我的 USB 摄像头从系统中消失。它从第一天开始就发生了,因为制造商驱动程序与 Linux 不兼容。 lsusb 和 dmesg 一开始正确显示,但在较长时间后有时会
我分发了包含多个 Go 服务的应用程序。其中一些使用 Kafka 作为数据总线。我能够使用 Jaeger 的 opentracing 追踪服务之间的调用。我在图表上绘制 Kafka 跨度时遇到问题,它
我是一名优秀的程序员,十分优秀!