在 Intel Kaby Lake 架构上获取最后一级缓存未命中数的确切代码是什么
What will be the exact code to get count of last level cache misses on Intel Kaby Lake architecture
我读了一篇有趣的论文,标题为 "A High-Resolution Side-Channel Attack on Last-Level Cache",想找出适合我自己的机器的索引哈希函数——即英特尔酷睿 i7-7500U(Kaby Lake 架构)——遵循这篇文章的线索工作。
到reverse-engineer散列函数,论文提到第一步为:
for (n=16; ; n++)
{
// ignore any miss on first run
for (fill=0; !fill; fill++)
{
// set pmc to count LLC miss
reset_pmc();
for (a=0; a<n; a++)
// set_count*line_size=2^19
load(a*2^19);
}
// get the LLC miss count
if (read_pmc()>0)
{
min = n;
break;
}
}
如何在 C++ 中编写 reset_pmc()
和 read_pmc()
代码?到目前为止,从我在网上阅读的所有内容来看,我认为它需要内联汇编代码,但我不知道使用什么指令来获取 LLC 未命中数。如果有人可以指定这两个步骤的代码,我将不胜感激。
我在 VMware 工作站上 运行 Ubuntu 16.04.1(64 位)。
P.S.: 我在 Intel Architectures Software Developer's Manual 的第 18 章第 3B 卷中发现了这些 LONGEST_LAT_CACHE.REFERENCES
和 LONGEST_LAT_CACHE.MISSES
的提及,但我不知道如何使用他们。
您可以按照 Cody 的建议使用 perf
从代码外部测量事件,但我从您的代码示例怀疑您需要对性能计数器进行细粒度的编程访问。
要做到这一点,您需要启用计数器的用户模式读取,并且还需要一种对它们进行编程的方法。由于这些是受限操作,您至少需要 OS 内核的一些帮助才能做到这一点。推出自己的解决方案将非常困难,但幸运的是,Ubunty 16.04 有几个现有的解决方案:
- Andi Kleen 的 jevents library, which among other things lets you read PMU events from user space. I haven't personally used this part of pmu-tools, but the stuff I have used has been high quality. It seems to use the existing perf_events 系统调用用于计数器编程,因此不需要内核模型。
- libpfc 库是内核模块和用户态代码的全新实现,允许用户态读取性能计数器。我用过这个并且效果很好。您安装允许您对 PMU 进行编程的内核模块,然后使用 libpfc 公开的 API 从用户空间读取计数器(调用归结为
rdpmc
指令)。这是读取计数器的最准确和精确的方法,它包括 "overhead subtraction" 功能,可以通过减去由 PMU 读取代码本身引起的事件,为您提供测量区域的真实 PMU 计数。您需要固定到单个内核以使计数有意义,如果您的过程被中断,您将得到虚假结果。
- 英特尔在 Windows 上开源了 Processor Counter Monitor library. I haven't tried this on Linux, but I used its predecessor library, the very similarly named1 Performance Counter Monitor,并且有效。在 Windows 上,它需要一个内核驱动程序,但在 Linux 上,您似乎可以使用驱动器或让它通过
perf_events
.
- 使用 likwid library's Marker API 功能。 Likwid 已经存在了一段时间并且似乎得到了很好的支持。我以前用过 likwid,但只是在类似
perf stat
的事情上测量整个过程,而不是用标记 API。要使用标记 API,您仍然需要 运行 您的进程作为 likwid 测量进程的子进程,但您可以通过编程方式读取进程中的计数器值,这正是您所需要的(据我了解它)。我不确定使用标记 API 时 likwid 如何设置和读取计数器。
所以你有很多选择!我认为它们都可以工作,但我个人可以保证 libpfc
,因为我自己在 Ubuntu 16.04 上出于相同的目的使用它。该项目正在积极开发,可能是上述项目中最准确(最少开销)的项目。所以我可能会从那个开始。
上面的所有解决方案都应该适用于 Kaby Lake,因为每个后续 "Performance Monitoring Architecture" 的功能似乎通常是前一个的超集,而 API 通常是保存。然而,在 libpfc
的情况下,作者在本地有 restricted it to only support Haswell's architecture (PMA v3), but you just need to change one line of code 来修复它。
1 事实上,它们通常都以首字母缩写 PCM 来称呼,我怀疑新项目只是官方的旧 PCM 项目的开源延续(也以源代码形式提供,但没有社区贡献机制)。
我会使用 PAPI,请参阅 http://icl.cs.utk.edu/PAPI/
这是一个得到很多支持的跨平台解决方案,尤其是来自 hpc 社区的支持。
我读了一篇有趣的论文,标题为 "A High-Resolution Side-Channel Attack on Last-Level Cache",想找出适合我自己的机器的索引哈希函数——即英特尔酷睿 i7-7500U(Kaby Lake 架构)——遵循这篇文章的线索工作。
到reverse-engineer散列函数,论文提到第一步为:
for (n=16; ; n++)
{
// ignore any miss on first run
for (fill=0; !fill; fill++)
{
// set pmc to count LLC miss
reset_pmc();
for (a=0; a<n; a++)
// set_count*line_size=2^19
load(a*2^19);
}
// get the LLC miss count
if (read_pmc()>0)
{
min = n;
break;
}
}
如何在 C++ 中编写 reset_pmc()
和 read_pmc()
代码?到目前为止,从我在网上阅读的所有内容来看,我认为它需要内联汇编代码,但我不知道使用什么指令来获取 LLC 未命中数。如果有人可以指定这两个步骤的代码,我将不胜感激。
我在 VMware 工作站上 运行 Ubuntu 16.04.1(64 位)。
P.S.: 我在 Intel Architectures Software Developer's Manual 的第 18 章第 3B 卷中发现了这些 LONGEST_LAT_CACHE.REFERENCES
和 LONGEST_LAT_CACHE.MISSES
的提及,但我不知道如何使用他们。
您可以按照 Cody 的建议使用 perf
从代码外部测量事件,但我从您的代码示例怀疑您需要对性能计数器进行细粒度的编程访问。
要做到这一点,您需要启用计数器的用户模式读取,并且还需要一种对它们进行编程的方法。由于这些是受限操作,您至少需要 OS 内核的一些帮助才能做到这一点。推出自己的解决方案将非常困难,但幸运的是,Ubunty 16.04 有几个现有的解决方案:
- Andi Kleen 的 jevents library, which among other things lets you read PMU events from user space. I haven't personally used this part of pmu-tools, but the stuff I have used has been high quality. It seems to use the existing perf_events 系统调用用于计数器编程,因此不需要内核模型。
- libpfc 库是内核模块和用户态代码的全新实现,允许用户态读取性能计数器。我用过这个并且效果很好。您安装允许您对 PMU 进行编程的内核模块,然后使用 libpfc 公开的 API 从用户空间读取计数器(调用归结为
rdpmc
指令)。这是读取计数器的最准确和精确的方法,它包括 "overhead subtraction" 功能,可以通过减去由 PMU 读取代码本身引起的事件,为您提供测量区域的真实 PMU 计数。您需要固定到单个内核以使计数有意义,如果您的过程被中断,您将得到虚假结果。 - 英特尔在 Windows 上开源了 Processor Counter Monitor library. I haven't tried this on Linux, but I used its predecessor library, the very similarly named1 Performance Counter Monitor,并且有效。在 Windows 上,它需要一个内核驱动程序,但在 Linux 上,您似乎可以使用驱动器或让它通过
perf_events
. - 使用 likwid library's Marker API 功能。 Likwid 已经存在了一段时间并且似乎得到了很好的支持。我以前用过 likwid,但只是在类似
perf stat
的事情上测量整个过程,而不是用标记 API。要使用标记 API,您仍然需要 运行 您的进程作为 likwid 测量进程的子进程,但您可以通过编程方式读取进程中的计数器值,这正是您所需要的(据我了解它)。我不确定使用标记 API 时 likwid 如何设置和读取计数器。
所以你有很多选择!我认为它们都可以工作,但我个人可以保证 libpfc
,因为我自己在 Ubuntu 16.04 上出于相同的目的使用它。该项目正在积极开发,可能是上述项目中最准确(最少开销)的项目。所以我可能会从那个开始。
上面的所有解决方案都应该适用于 Kaby Lake,因为每个后续 "Performance Monitoring Architecture" 的功能似乎通常是前一个的超集,而 API 通常是保存。然而,在 libpfc
的情况下,作者在本地有 restricted it to only support Haswell's architecture (PMA v3), but you just need to change one line of code 来修复它。
1 事实上,它们通常都以首字母缩写 PCM 来称呼,我怀疑新项目只是官方的旧 PCM 项目的开源延续(也以源代码形式提供,但没有社区贡献机制)。
我会使用 PAPI,请参阅 http://icl.cs.utk.edu/PAPI/ 这是一个得到很多支持的跨平台解决方案,尤其是来自 hpc 社区的支持。