缓存阻塞对 ARM 上的图像过滤器没有任何改进

问题描述

我正在试验缓存阻塞。为此,我实现了 2 个基于卷积的平滑算法。我使用的高斯内核如下所示:

enter image description here

一个算法只是简单的 double for 循环,从左到右,从上到下循环,如下所示。

enter image description here

图片来源:(https://people.engr.ncsu.edu/efg/521/f02/common/lectures/notes/lec9.html)

在第二个算法中,我尝试通过将循环分成块来玩缓存阻塞,这变成了如下所示。我使用了 512x512 的块大小。

enter image description here

图片来源:(https://people.engr.ncsu.edu/efg/521/f02/common/lectures/notes/lec9.html)

我在 raspBerry pi 3B+ 上运行代码,我相信它有一个 Cortex-A53,L1 为 32KB,L2 为 256KB。我用不同的图像尺寸(2048x1536、6000x4000、12000x8000、16000x12000。8位灰度图像)运行了两种算法。但在不同的图像尺寸中,我发现运行时间非常相似。

问题是一个算法不应该遇到第二个不应该的访问延迟,尤其是在使用大尺寸图像(如 12000x8000)时。根据本link中缓存阻塞的描述,当使用第一种算法处理图像行末尾的数据时,行首的数据应该已经从L1缓存中驱逐了。以12000x8000大小的图片为例,由于我们使用的是5x5内核,所以需要5行数据,即12000x5=60KB,已经比32KB的L1大小大了。当我们开始处理新行的数据时,仍然需要 4 行以前的数据,但它们可能在 L1 中消失了,因此需要重新获取。但是对于第二种算法它不应该有这个问题,因为块大小很小。谁能告诉我我错过了什么?

我还使用 oprofile 和以下数据分析了算法:

算法 1

事件 计数
L1D_CACHE_REFILL 13,933,254
PREFETCH_LINEFILL 13,281,559

算法2

事件 计数
L1D_CACHE_REFILL 9,456,369
PREFETCH_LINEFILL 8,725,250

所以看起来第一个算法与第二个算法相比确实有更多的缓存未命中,这反映在 L1D_CACHE_REFILL 计数上。但它也有更高的数据预取率,这可能是由于循环的简单行为。那么缓存阻塞的整个故事是不是没有考虑数据预取?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)