在这种情况下:
我通过网络在一个单独的线程中通过 TCP 将大约 1MB 的数据接收到缓冲区中。
对该缓冲区进行解压缩会产生大约 2MB 的数据。
对我拥有源的同一个动态链接库函数的两次调用。基本上是一堆使用 FFTW 3.3.3 并支持 NEON 的 FFT。我认为第一组 FFT 是冷的,第二组是热的。
冷运行比热运行慢大约 200 毫秒:
- 冷:570 毫秒
- 热:260 毫秒
如果 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 个案例,如下所示: 如何导致指令缓存未命中?
如果我将 FFT 操作的数据复制到内存不同部分的重复结构中,然后对复制进行操作,它与刷新 L2 的效果不同。
我想了解发生了什么。我在 Tegra 3 上强制将进程和线程关联到单个内核。我可以进行或查看哪些其他易于访问的测量?