为什么执行的 AVX 指令数会随处理器系列而变化
Why does the number of executed AVX instructions change with processor family
我已经使用内部函数实现了一个简单的 AVX 程序,它是用 -march=core-avx2 -O3
的 icc 编译的。该程序不检测多线程。
在分析程序的执行时,我用 PAPI 库测量了实际执行的 AVX(256 位浮点运算)的数量。
当我在不同的处理器(即 Sandy Bridge、Haswell 和 Skylake 的 Core-i7)上执行程序时,SB 和 Skylake 架构的执行指令数量几乎相同,但 Haswell 更高(+50%)架构。
据我了解,生成的汇编程序指令在体系结构之间没有区别,因为未使用 -march=native
。
执行和书面操作的差异从何而来?是否有一些 hardware/instructions 的微代码模拟。或者是否发生了一些特定于体系结构的计数过多?
该问题至少应分为两个问题:1) 两次运行之间的计数器是否应该相同? 2)报告的数字可以信任吗?第一个问题解决了您的方法中可能的变化来源,第二个问题解决了您使用的工具的细节(PAPI 和它使用的底层硬件计数器)。
运行 两个系统上的二进制文件相同。不是从同一个源编译的两个程序,而是同一个二进制文件复制到它们。如果这将 AVX 指令的测量值放在一起,那么问题是单独的编译生成不同的代码。
简化程序代码,使生成的指令数易于猜测。使用具有硬编码迭代次数的循环,内部有线性代码块,并且 PAPI 调用就在循环周围。这样,您就可以预测结果,然后将其与报告的数字进行比较。您使用内在函数,因此 可能会假设 编译器优化不应影响从它们生成的代码。但将优化级别降低到 -O0
以确保编译器使用最少的技巧,例如动态处理器调度。
让程序更简单。在任何循环之外只留下一条 AVX 指令。 PAPI 会报告什么?留下零。 PAPI的报告还会符合预期吗?
这些技术应该足以从逻辑上推断问题是否出在独立二进制文件的构建过程中的差异、在不同硬件上的单个二进制文件中选择的运行时路径的差异、不正确的 PAPI 使用或普通的 PAPI 错误,可能是由以下原因引起的底层硬件对指令计数不可靠。顺便说一下,您没有显示任何代码,所以您很可能忘记初始化某些东西,或者有不同的迭代次数,或者您的方法中有类似的遗漏。
我已经使用内部函数实现了一个简单的 AVX 程序,它是用 -march=core-avx2 -O3
的 icc 编译的。该程序不检测多线程。
在分析程序的执行时,我用 PAPI 库测量了实际执行的 AVX(256 位浮点运算)的数量。
当我在不同的处理器(即 Sandy Bridge、Haswell 和 Skylake 的 Core-i7)上执行程序时,SB 和 Skylake 架构的执行指令数量几乎相同,但 Haswell 更高(+50%)架构。
据我了解,生成的汇编程序指令在体系结构之间没有区别,因为未使用 -march=native
。
执行和书面操作的差异从何而来?是否有一些 hardware/instructions 的微代码模拟。或者是否发生了一些特定于体系结构的计数过多?
该问题至少应分为两个问题:1) 两次运行之间的计数器是否应该相同? 2)报告的数字可以信任吗?第一个问题解决了您的方法中可能的变化来源,第二个问题解决了您使用的工具的细节(PAPI 和它使用的底层硬件计数器)。
运行 两个系统上的二进制文件相同。不是从同一个源编译的两个程序,而是同一个二进制文件复制到它们。如果这将 AVX 指令的测量值放在一起,那么问题是单独的编译生成不同的代码。
简化程序代码,使生成的指令数易于猜测。使用具有硬编码迭代次数的循环,内部有线性代码块,并且 PAPI 调用就在循环周围。这样,您就可以预测结果,然后将其与报告的数字进行比较。您使用内在函数,因此 可能会假设 编译器优化不应影响从它们生成的代码。但将优化级别降低到
-O0
以确保编译器使用最少的技巧,例如动态处理器调度。让程序更简单。在任何循环之外只留下一条 AVX 指令。 PAPI 会报告什么?留下零。 PAPI的报告还会符合预期吗?
这些技术应该足以从逻辑上推断问题是否出在独立二进制文件的构建过程中的差异、在不同硬件上的单个二进制文件中选择的运行时路径的差异、不正确的 PAPI 使用或普通的 PAPI 错误,可能是由以下原因引起的底层硬件对指令计数不可靠。顺便说一下,您没有显示任何代码,所以您很可能忘记初始化某些东西,或者有不同的迭代次数,或者您的方法中有类似的遗漏。