矢量化代码中随机减速的原因
Posted
技术标签:
【中文标题】矢量化代码中随机减速的原因【英文标题】:Reason for random slowdown in vectorized code 【发布时间】:2017-02-01 05:01:39 【问题描述】:我在一个项目中使用 AVX2、AVX 和 SSE 编译器内在函数编写了一个特定函数。我知道当 CPU 在 AVX/AVX2 和 SSE 模式之间更改状态时会受到惩罚,因此我在 Visual Studio 项目设置中将增强指令集设置为 AVX2。
在我的代码中,我在 for 循环中反复使用了一些数据。我的代码结构大致如下所示:
//I gather the data that I am going to access again and again and put them
//into variables so that I use minimal array indexing
__m256 a = (code to get a)
__m256 b = (code to get b)
.........
for(int i =0; i < large number; i++)
c = arrayofc[i];
//operate with a and b and other variables gathered outside the loop.
d+= result of operations;
我面临的问题是,这个函数执行得非常好,但是在程序的某些运行中它会减慢 10 到 15 倍,而同一程序中的其他函数最多会减慢 2 倍.
我使用加速计时器来测量性能、Visual Studio 性能分析器和 GPU 视图。所有这些都表明在我的程序的某些运行中,这个函数执行得非常慢。我的程序没有给出随机结果;每次它给出相同的结果。
GPUview 也没有显示任何其他线程干扰此功能。
曾经我以为我缓存了我的变量,并且在循环内部它只是浮点矢量化操作,打开的 Intel Speed Step 减慢了这个函数,特别是因为这个函数可能比 CPU 更依赖其他可能更依赖内存的功能。但是我的猜测结果是错误的,因为我在禁用 Intel Speed Step 的情况下进行了测试,但仍然遇到了同样的问题。
我也使用软件预取来缓存我在循环外收集的变量,但没有任何好处。
我仍然不确定这是否是由虚拟化引起的。我正在使用的计算机的任务管理器显示 CPU 利用率非常低(1-5%)。内存利用率约为 40%,有时磁盘利用率约为 100%
我们将不胜感激有关此问题的任何帮助。
【问题讨论】:
如果没有某种minimal reproducible example,我认为任何人都无法提供太多帮助。 可能是线程迁移、CPU 热节流、后台驱逐缓存上运行的其他进程(以及其他我想不到的原因)的结果... 任何奇怪的值,例如非正规值? 【参考方案1】:@Paul R 抱歉这个问题有点含糊。
@Rotem 我认为原因是缓存被驱逐。
@Harold 它与非正规化无关,因为每次我得到相同的结果,如果它受到非正规化的影响,它每次都会影响进程。
我可能找到了问题的答案,但我现在无法验证。我会尽快发布测试结果。
我在函数中所做的是,为了减少数组索引并最大限度地使用寄存器,我将数组中的一些数据放入变量中。
比如我要访问 Darray[0], Darray[1] ...... Darray[6];
在循环开始时我使用了代码
__m256 D0 = 数组[0]; __m256 D1 = 数组[1];
等等。大多数情况下,编译器生成汇编代码,其中变量被放入寄存器并使用寄存器,但在这种情况下,寄存器压力太高,它们没有被放入寄存器,而是被放入不同的内存位置。我打印出 D0 的地址以及与其他变量 D1 、 D2 .... 等的地址差异
这是我得到的结果(第一个数字是 D0 的地址,接下来是它的偏移量):
280449315232 -704 -768 -640 -736 -608
尽管我按顺序访问代码中的变量,但有时它们相距甚远。
这是另一个数组的结果(这个最令人惊讶)
280449314144 416 512
另一个:
812970176 128 192 256 224 160 1152
因此,当我访问一个变量时,我不太可能将另一个变量放入缓存中。但是通过循环的一次迭代,我可能会将所有变量都放入缓存中,但是其他一些程序可以随时将它们从缓存中删除。如果我使用数组,即使我提取到缓存中的变量可以从缓存中删除,当我访问其他元素时,我最终也会将一些元素带到缓存中。
我将再次对大部分数据使用数组,并尝试将其余数据放入寄存器中。我将在这篇文章中进行基准测试并报告我的发现。
谢谢。
【讨论】:
很公平,我只是想您可能正在测试每次都更改的随机值或类似的东西。以上是关于矢量化代码中随机减速的原因的主要内容,如果未能解决你的问题,请参考以下文章