[db:标题]
摘要:充分利用系统的Write Combine Buffer可以加速一些内存读写占比很大的基础算法的实现,从而为其他一些复杂算法提供便利。
最新博客园有博主连续发表了3篇高性能优化方面的文章,其链接分别如下:
高性能计算实践-OpenCV图像翻转 flip SIMD加速(ippicv)复现
高性能计算实践-OpenCV图像矩阵转置 transpose SIMD加速(ippicv)复
高性能计算实践-遥遥领先!看看 streaming store 在矩阵转置中有多少提升
其核心都指向了一个关键的Intrinsics函数: _mm_stream_si128,我们在Intel的官方文档里能找到其相关的解释如下:
这个解释很简单,最明显的要求是内存地址必须是16字节对齐的。似乎看不出什么核心的信息。
以前我也尝试过使用这个函数去处理,很多情况下发现对算法的执行结果没有什么优化。但是通过刚刚那三篇文章,确实发现在特定的场合下恰当的使用他确实能带来不晓得新能提升。
一个核心的概念就是隐藏在这个函数背后的一些写内存机制(Write Combine Buffer),鉴于自己对硬件的一知半解,我也不能说出个所以然来,百度也看了半天,把一些只言片语整理下分享下吧:
Write Combine Buffer 简介
Write Combine Buffer(写合并缓冲区)是处理器内存系统中的一个组件,主要用于优化写操作性能。当启用写合并机制时,CPU会将写入的数据先暂存到这个缓冲区,然后以突发(burst)传输方式高效地推送到系统总线。这种方式能显著减少内存访问延迟,因为从缓冲区推送数据的延迟(约10多纳秒)远低于直接从主内存读取的延迟(约100多纳秒),从而提升写吞吐量。
缓冲区特性:WC缓冲区大小和条目数量有限,具体取决于CPU架构(如Intel Skylake处理器有4个可用WC缓冲区)。 缓冲区仅对同一缓存行的写操作有效,若后续写操作地址分散,则无法合并。
适用场景:最适合连续、非有序的写入,如图形内存、日志记录等。对于需要强一致性的内存区域(如普通程序数据),应避免使用WC模式,以免引发数据竞争。
当CPU执行一个Store操作时,它将会把数据写到离CPU最近的L1的数据缓存,如果这个时候发生Write miss, 则CPU将会去L2缓存为了减少Write Miss带来的性能开销,Intel和其它很多型号的CPU都引入了Write Combining 技术。Write Combining Buffer不是编程时内存里的Buffer,而是CPU里面真实的存储单元,是硬件。
当发生L1 Write Miss时,WC 可以把多个对同一缓存行Store操作的数据放在WC中,在程序对相应缓存行(或者理解为这些数据)读之前先合并,等到需要读取时再一次性写入来减少写的次数和总线的压力。此时,CPU可以在把数据放入WC后继续执行指令,减少了很多时钟周期的浪费。不同的CPU, WC的数量可能是不一样的。Intel的CPU中,其实只有4个WC可以真正被我们同时使用。
_mm_stream_si128 指令说明
_mm_stream_si128是SSE指令集中的一个内置函数(intrinsics),用于执行非临时写操作。它属于MOVNT(Move Non-Temporal)类指令,旨在将数据直接写入内存而不污染缓存(即不将数据加载到L1/L2缓存中),适用于大数据量传输场景,如流式数据处理。
功能:该指令将128位数据(如__m128i类型)写入指定内存地址,通常用于避免缓存争用,提升内存带宽利用率。
与写合并的关系:虽然公开资料未直接说明_mm_stream_si128是否利用写合并缓冲区,但非临时写操作通常与写合并机制兼容。这是因为写合并缓冲区专门处理延迟写合并以优化性能,而_mm_stream_si128的非临时特性可能使其更高效地利用缓冲区,减少缓存污染。不过,具体行为取决于CPU架构和内存类型(如写合并内存类型WC)。
以上的一些资料都说明这个写操作可能绕过L1缓存,直接在合适的时间将数据以块为单位写入内存,这个块查阅有关资料说在P6之前的电脑是32字节,现在基本每个块的大小都是64字节。
在高性能计算相关的文章中,作者使用了转置这个算法为例,说明了使用这个方法加速算法速度的过程,这里稍微简单的重复下。
何为转置---> 转置是行变为列,列变为行的一个过程,这个里面不存在什么计算,就是取数据然后写数据。
