问题标签 [auto-vectorization]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
454 浏览

visual-c++ - MSVC 2017 是否支持自动 CPU 调度?

我在一些网站上读到,当使用 SSE2 架构并检测 AVX 支持运行时时,MSVC 实际上可以发出 AVX 指令。这是真的吗?

我测试了各种肯定会受益于 AVX/AVX2 支持的循环,但是当在调试器中运行时,我真的找不到任何 AVX 指令。

当使用 /arch:AVX 时,它会发出 AVX 指令,但它当然会在不支持它的 CPU 上崩溃(经过测试),因此也没有运行时检测。我可以使用 AVX 内在函数,它会成功地从它们创建 AVX 指令。有任何想法吗?

0 投票
2 回答
351 浏览

c++ - 为什么 p1007r0 std::assume_aligned 不需要结语?

我的理解是代码的矢量化是这样工作的:

对于数组中的数据,数组中的第一个地址是 128(或 256 或任何 SIMD 指令要求的)的倍数,逐个元素地进行缓慢的处理。让我们称之为序幕。

对于数组中第一个地址是 128 的倍数和最后一个地址是 128 的倍数之间的数据,使用 SIMD 指令。

对于最后一个地址为 128 的倍数和数组末尾之间的数据,使用慢元素逐个元素处理。让我们称之为结语。

现在我明白了为什么std::assume_aligned有助于序言,但我不明白为什么它也能让编译器删除结尾。

引用提案:

如果我们可以让这个属性对编译器可见,它可以跳过循环序言和结尾

0 投票
2 回答
3086 浏览

c - 通过 OpenMP SIMD 进行 256 位矢量化会阻止编译器的优化(比如函数内联)?

考虑以下玩具示例,其中A是以n x 2列优先顺序存储的矩阵,我想计算其列总和。sum_0仅计算第一列的总和,而sum_1第二列也计算。这实际上是一个人为的例子,因为基本上不需要为这个任务定义两个函数(我可以编写一个带有双循环嵌套的单个函数,其中外循环从0to迭代j)。它的构造是为了演示我在现实中遇到的模板问题。

如果我编译它

GCC(比如最新的 8.2),在内联、持续传播和死代码消除之后,将优化涉及c1for 函数的代码sum_0在 Godbolt 上检查)。

我喜欢这个把戏。通过编写单个模板函数并传入不同的配置参数,优化编译器可以生成不同的版本。它比复制和粘贴大部分代码并手动定义不同的功能版本要干净得多。

但是,如果我激活 OpenMP 4.0+

sum_template不再内联,也没有应用死代码消除(在 Godbolt 上检查)。但是,如果我删除标志-mavx以使用 128 位 SIMD,编译器优化会按我的预期工作(在 Godbolt 上检查)。那么这是一个错误吗?我在 x86-64 (Sandybridge) 上。


评论

使用 GCC 的自动矢量化-ftree-vectorize -ffast-math不会有这个问题(在 Godbolt 上检查)。但我希望使用 OpenMP,因为它允许跨不同编译器的可移植对齐编译指示。

背景

我为 R 包编写模块,它需要跨平台和编译器移植。编写 R 扩展不需要 Makefile。当 R 在平台上构建时,它知道该平台上的默认编译器是什么,并配置一组默认编译标志。R 没有自动矢量化标志,但它有 OpenMP 标志。这意味着使用 OpenMP SIMD 是在 R 包中使用 SIMD 的理想方式。有关详细信息,请参见12

0 投票
1 回答
1514 浏览

gcc - GCC 自动矢量化

在 gcc 编译器中有没有办法只启用自动矢量化?我确实知道该-ftree-vectorize标志可以启用自动矢量化。但它至少需要-O2优化级别。有没有办法在不使用-O2优化标志的情况下启用自动矢量化?

提前致谢。

0 投票
2 回答
422 浏览

gcc - 为什么 gcc -O3 自动矢量化阶乘?那么多额外的指令看起来更糟

这是一个非常简单的阶乘函数。

GCC 在 -O2 上对此函数的汇编是合理的。

然而,在 -O3 或 -Ofast 上,它决定让事情变得更复杂(几乎 100 行!):

我使用 Compiler Explorer 获得了这些结果,因此在实际用例中应该是相同的。

那是怎么回事?在任何情况下这会更快吗?Clang 似乎也在做类似的事情,但是在 -O2 上。

0 投票
1 回答
352 浏览

c++ - 循环中标量积的自动矢量化

我正在尝试自动矢量化以下循环。下面我们用i-andj-循环遍历矩阵的下三角形。不幸的是,矢量化报告无法矢量化(=转换为 AVX SIMD 指令)j 循环和 k 循环。但我认为这很简单,因为没有指针别名(#pragma ivdep和编译器选项-D NOALIAS)并且数据(x:一维数组和 p:一维数组)对齐到 64 个字节。

- 语句可能if是个问题,但即使使用if-free 解决方案(昂贵的移位操作和计算双精度符号),编译器也无法向量化此循环。

它是否指的是每个 OpenMP 线程的 OpenMP 起点直到运行时才知道的问题?我认为这解决了该simd子句,并且英特尔的自动矢量化意识到了这一点。

英特尔编译器:18.0.2 20180210

编辑:我已经查看了程序集,现在很明显代码已经被矢量化了,很抱歉让你们所有人接受。

0 投票
1 回答
43 浏览

templates - 为什么 MSVC12 的自动矢量化器不分析函数模板?

VS2013 中的自动矢量化或自动并行器 (/Qpar) 引擎看不到函数模板。

例如,这段代码:

似乎已被识别,我从 /Qvec-report:2 和 /Qpar-report:2 获得了适当的输出:

但是,一旦我someFunc()变成一个函数模板:

我从日志中的自动矢量化器或自动并行化器中一无所获:

我没有使用 /GL,如Why would /Qvec-report:2 return nothing 中所述?(MSVC 2012)

0 投票
1 回答
582 浏览

java - Java 自动向量化

我试图了解 JDK 何时会自动矢量化。我有以下一组问题(尽管谷歌搜索、阅读、实验等)。给定一个简单的循环如下:

  1. 为什么需要内联方法调用“method1”(出现在循环中)以进行自动矢量化?(我不明白为什么必须这样做......)
  2. 也许这是一个“愚蠢”的问题,但如果“someObject.method2()”未被注释怎么办。(让我们假设method2 是巨大的方法,即很多行)。这也会阻止自动矢量化吗?如果 method2 是一个很小的方法(例如,只有 1 或 2 行等?)
  3. 如果未注释“someHashMap”行怎么办?我们有一个可以在所有 SIMD 中共享的对象/变量这一事实是否也会导致自动矢量化失败?(我看不到它是如何工作的,除非 jdk 在访问“someHashMap”的公共对象/var 时以某种方式自动插入“同步”关键字
  4. 在我看来,“流”接口将解决上面问题#3 中隐含的问题,因为流中的“收集器”逻辑会自动处理合并单个哈希图,因此我们不需要任何“同步”词。(而且总的来说,流式 API 似乎是一个完美的 API,可以让 jdk 自动使用自动矢量化,只要在创建流式代码时没有“外部变量”(即没有副作用)...... jdk /jit 编译器会在使用标准流接口编写代码时自动执行自动向量化?如果没有,这样做是否有意义(可能在未来的 jdk 版本中,或者可能来自其他供应商的 jdk?)
  5. 如果循环体包含很多 if 语句等(很多分支,让我们进一步说每个分支都进行大量计算),这是否意味着 a)自动向量化可能是一个坏主意(就像它对于 GPU 一样) 和 b) jit 编译器足够聪明,可以确定自动向量化是一个坏主意,因此它不会自动向量化?
  6. 我目前正在使用 Oracle jdk8,但是如果使用 jdk9 或 jdk10 等,上面的答案会改变吗?
0 投票
0 回答
73 浏览

c++ - clang:在错误消息中打印当前模板

我有代码#pragma clang loop vectorize(enable),它强制矢量化。对于某些类型,这种矢量化是不可能的 - 例如:

https://godbolt.org/z/EgiogQ

Clang 给了我一个警告:

如果我不知道 的std::string初始化double_entries导致问题,这并没有真正的帮助。

有什么方法可以让我打印所有涉及的模板实例?一旦我可以使用该编译器输出识别有问题的类型,我就可以简单地禁用这些类型的矢量化。

0 投票
1 回答
94 浏览

c++ - 由于 cout,GCC 4.8.2 自动矢量化失败

我的代码如下,我使用 GCC 4.8.2:

我用它编译

gcc -lstdc++ -std=c++11 -O2 -ftree-vectorize -ftree-vectorizer-verbose=7 -fopt-info test.cpp

我明白了test.cpp:14: note: not vectorized: not enough data-refs in basic block.

然后我运行二进制文件a.out并得到COST超过 20000 个。

如果我 delete std::cout << "TEST: " << a << endl;,则此代码是矢量化的并且COST小于 100。

任何人都可以帮助我。