在这种情况下:
我通过网络在单独的线程中通过TCP接收大约1MB的内存。
对此缓冲区进行解压缩会产生大约2MB的数据。
两次调用我拥有源的相同动态链接库函数。 基本上是使用FFTW 3.3.3和NEON支持的一堆FFT。第一套 FFT我认为冷,第二热。
冷运行比热运行慢约200毫秒:
如果1.)和2.)被完全相同数据的文件中的读取所取代,那么热和冷运行同样快。
如果我将网络数据减少到大约200K,从而将解压缩的数据减少到400K,那么冷热之间的性能是相同的。
如果我在 2之后立即执行L2冲洗*。),冷性能会增加到与热性能相同。我不明白这一点。我已经尝试更改了许多编译器选项,只要使用优化器,我就会看到这种行为。
如果我冲洗更少的缓存,那么冷运行的性能会按比例恶化。
*这是我用来尝试刷新1MB L2缓存的代码:
const size_t cache_size = 1024 * 1024;
char *cache = new char[cache_size];
srand(1);
for (size_t dc = 1; dc < cache_size; ++dc)
{
cache[dc] = cache[dc - 1] + rand() * 255;
}
使用巨型switch语句来刷新指令缓存没有太大影响。我使用了32,000个案例,如下所示: How can I cause an instruction cache miss?
如果我将FFT操作的数据复制到存储器的不同部分中的复制结构,然后在复制时操作,则它与刷新L2的效果不同。
我想了解发生了什么。我强制将流程和线程关联性强加到Tegra 3上的单个核心。我可以制作或查看哪些其他易于访问的测量?
答案 0 :(得分:1)
如果缓存配置为回写(通常性能更高),则刷新会导致第一个FFTW的所有输出都写入内存,而不是等到第二个FFTW需要缓存行。因此缓存是空的而不是被脏线污染。