2

在这种情况下:

  1. 我通过网络在一个单独的线程中通过 TCP 将大约 1MB 的数据接收到缓冲区中。

  2. 对该缓冲区进行解压缩会产生大约 2MB 的数据。

  3. 对我拥有源的同一个动态链接库函数的两次调用。基本上是一堆使用 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 上强制将进程和线程关联到单个内核。我可以进行或查看哪些其他易于访问的测量?

4

1 回答 1

1

如果缓存配置为回写(这通常是更高的性能),那么您的刷新会导致第一个 FFTW 的所有输出都写入内存,而不是等到第二个 FFTW 需要缓存行。所以缓存是空的,而不是被脏行污染。

于 2013-02-11T22:45:47.497 回答