- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
因此,我们的任务是编译一些代码(我们应该将其视为黑盒),使用不同的英特尔编译器优化标志(-O1 和 -O3)以及矢量化标志(- xhost 和 -no-vec) 并观察以下方面的变化:
执行这些优化后,我们注意到执行时间有所缩短,这是意料之中的事情,考虑到编译器为提高效率而对您的代码所做的所有更改。然而,我们也注意到 FPO 的数量有所下降,虽然我们知道这是一件好事,但我们不确定为什么会这样。此外,我们注意到(并且无法解释)L2 缓存未命中率增加(随着优化级别的增加而增加),但缓存访问没有显着增加,L3 级别几乎没有变化。
完全不使用矢量化或优化在 L2 缓存未命中率方面产生了最佳结果,我们想知道你们是否可以给我们一些见解,以及我们可以使用的支持文档、文献和资源加深我们对这个主题的了解。
谢谢。
编辑:使用的编译器选项是:
更新:
虽然总体 L2 缓存访问略有下降,但实际未命中率却大幅增加。
使用 -0O -no-vec
以 usecs 为单位的挂钟时间:13,957,075
使用-xhost
以 usecs 为单位的挂钟时间:4,465,243
最佳答案
EOF 的回答对较少的浮点操作有很好的解释:-ffast-math
操作组合,所以我只回答另一部分。
这个问题没有关于使用什么 CPU 微架构的信息,但至少它被标记为 intel .
在 Intel CPU 上,有一些逻辑可以预取到 L1,还有更复杂的逻辑可以预取到 L2(从 L3 或主内存)。每个内核都有自己的 L2,但缓存层次结构的较低级别是共享的,因此它是放置主要预取逻辑的明显位置。
如果您的读取速度低于内存带宽的限制,您的负载将在 L2 中命中,因为硬件预取器已经将这些行提取到 L2 中。 如果预取跟不上,您将导致 L2 缓存未命中。
更少的更宽负载而不是更多的标量负载也意味着 vector 的未命中百分比会更糟。 (EOF 的回答已经说明了这一点)。这种影响并不能解释 L2 未命中绝对数量的增加,但只有(部分)未命中百分比发生变化。不过,在查看数据时仍需牢记这一点。
来自 Intel 的优化指南(x86 标签 wiki 中的链接),第 2.3.5.4 节:数据预取:
Data Prefetch to the L2 and Last Level Cache
Streamer: This prefetcher monitors read requests from the L1 cache for ascending and descending sequences of addresses.... When a forward or backward stream of requests is detected, the anticipated cache lines are prefetched. Prefetched cache lines must be in the same 4K page.
- The streamer may issue two prefetch requests on every L2 lookup. The streamer can run up to 20 lines ahead of the load request.
- Adjusts dynamically to the number of outstanding requests per core. If there are not many outstanding requests, the streamer prefetches further ahead. If there are many outstanding requests it prefetches to the LLC only and less far ahead.
- When cache lines are far ahead, it prefetches to the last level cache only and not to the L2. This method avoids replacement of useful cache lines in the L2 cache.
- Detects and maintains up to 32 streams of data accesses. For each 4K byte page, you can maintain one forward and one backward stream can be maintained.
这是来自 Sandybridge 部分,但 Haswell 和 Skylake 部分没有详细介绍预取的更改。他们说“改进的预取”,但大概是相同的基本设计,只是具有更好的启发式算法和/或对现有启发式算法进行更好的调整,诸如此类。
感谢@HansPassant:他对这个问题的评论让我想到预取跟不上。
关于编译器优化对使用 PAPI 的 FLOP 和 L2/L3 缓存未命中率的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26638572/
我正在尝试学习papi api来监控各种CPU事件的性能。首先,我运行了 PAPI 官方文档提到的示例片段之一。下面是代码 #include #include #include "papi.h" #
我正在使用 PAPI 库来调整和分析我的应用程序。 我想知道 (PAPI_REF_CYC : Reference clockcycles ) 实际上是什么意思? 提前致谢, 最佳答案 一些现代 CPU
当今的大多数处理器都配备了硬件性能计数器。此类计数器可用于对微架构事件进行计数,以便分析目标程序以提高其性能。通常,分析和分析是这些计数器的主要目标。 根据文献中的研究论文,这些计数器缺乏准确性。例如
我从网站上下载了 4.4 版本,将其构建在我自己的目录中,并尝试编写一个小主程序,但它一直显示 num_counters 为零。然后我查看了 ctests 并选择了 hwinfo.c,并从中删除了一些
我正在尝试在 Arch Linux x86_64 中构建一些使用 PAPI 5.4.3.0 库的项目。 为了简单起见,我在这两个文件中复制了我不明白的东西: A.cpp #include "strin
是否有可能找到映射到 PAPI 事件的 native 事件集(CPU 计数器寄存器)? 最佳答案 如果你安装了 papi,你可以使用 papi_avail 来获取本地事件。例如, papi_avail
我使用了 cdecl 并将其定义为“将 papi 声明为指向 int 指针的指针的数组 10”所以我这样写我的代码 int i = 10; int *api[10]; api[0] = &i; int
我正在尝试使用 PAPI 读取硬件性能计数器,并且我编写了以下代码: #include #include #include "papi.h" /* This needs to be include
我正在尝试使用 PAPI 读取其中一个硬件计数器。当我尝试从 perf_event 列表中读取事件时,它工作正常。但是现在我需要从 perf_event_uncore 列表中读取一个计数器,它是通过
我正在尝试使用 papi 进行测试,但遇到一些错误,我不明白为什么会发生这些错误。我在网上找不到任何适合他们的东西。代码如下 我正在使用PAPI和C。 #include #include #inc
我正在做一个项目,我只需要使用 clang 生成位码,使用 opt 运行一些优化过程,然后创建一个可执行文件并测量其硬件计数器。 我可以直接使用 clang 链接: clang -g -O0 -w -
我试图在我的桌面上的 ubutu 16.4 上安装 papi。我面临错误,我找不到任何解决方案。也许是因为这是我第一次使用 Papi。我从 http://icl.cs.utk.edu/papi/sof
我正在使用 PAPI 高级 API 检查循环遍历数组的简单程序中的 TLB 未命中,但看到的数字比预期的要大。 在其他简单的测试用例中,结果似乎相当合理,这让我认为结果是真实的,额外的未命中是由于硬件
我正在使用 PAPI 高级 API 检查循环遍历数组的简单程序中的 TLB 未命中,但看到的数字比预期的要大。 在其他简单的测试用例中,结果似乎相当合理,这让我认为结果是真实的,额外的未命中是由于硬件
因此,我们的任务是编译一些代码(我们应该将其视为黑盒),使用不同的英特尔编译器优化标志(-O1 和 -O3)以及矢量化标志(- xhost 和 -no-vec) 并观察以下方面的变化: 执行时间 浮点
我正在开展一个项目,我们必须实现一种理论上证明对缓存友好的算法。简单来说,如果 N 是输入,B 是每次缓存未命中时在缓存和 RAM 之间传输的元素数,算法将需要 O(N/B) 访问 RAM。 我想证明
我是一名优秀的程序员,十分优秀!