问题标签 [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.
parallel-processing - 编译器通常会在未明确告知这样做时发出向量 (SIMD) 指令吗?
C++17 为标准库添加了并行扩展(例如std::sort(std::execution::par_unseq, arr, arr + 1000)
,这将允许使用多线程和向量指令进行排序)。
我注意到微软的实验性实现提到 VC++ 编译器在这里缺乏对向量化的支持,这让我感到惊讶——我认为现代 C++ 编译器能够推断循环的向量化能力,但显然 VC++ 编译器/优化器无法生成即使明确告知这样做,SIMD 代码也是如此。似乎缺乏自动矢量化支持与2011 年这个问题的答案相矛盾的答案相矛盾,这表明编译器将在可能的情况下进行矢量化。
也许,编译器只会向量化非常明显的情况,例如std::array<int, 4>
,仅此而已,因此 C++17 的显式并行化将很有用。
因此我的问题是:当前的编译器是否会在未明确告知我的代码时自动向量化我的代码?(为了使这个问题更具体,让我们将其范围缩小到支持 SIMD 的 Intel x86 CPU,以及最新版本的 GCC、Clang、MSVC 和 ICC。)
作为扩展:其他语言的编译器是否可以更好地进行自动矢量化(可能是由于语言设计)(以便 C++ 标准委员会决定显式(C++ 17 风格)矢量化是必要的)?
gcc - 如果没有 -ffinite-math-only,GCC 6.3.1 不会自动矢量化
我想了解为什么 GCC 不自动矢量化以下循环,除非我通过 -ffinite-math-only。至于我的理解和 GCC 手册,优化需要-funsafe-math-optimizations
如果选定的浮点硬件包括 NEON 扩展(例如 -mfpu=neon),请注意浮点运算不是由 GCC 的自动矢量化过程生成的,除非还指定了 -funsafe-math-optimizations。这是因为 NEON 硬件没有完全实现浮点运算的 IEEE 754 标准(特别是非正规值被视为零),因此使用 NEON 指令可能会导致精度损失。
特别是,该标志使编译器能够假设关联数学,以便它可以首先累加 4 个部分和。代码看起来很简单
未矢量化的循环
例如,平方加法看起来像
-ffinite-math-only
这样就变成了
编译器标志
-funsafe-math-optimizations -ffinite-math-only -mcpu=cortex-a9 -mfpu=neon
c++ - 叮当声:错误:未知参数:'-no-vec'
我正在尝试使用不同的选项在 c++ 中(在 macOS 10.12.6 上)编译一些东西,并-no-vec
使用-vec-report
诸如g++-6
. 我对 c++ 并不陌生,但几年前我曾经编写过代码(在 linux 上,从来没有在 mac 或任何其他东西上),我目前正在使用 geany,只是在终端上编译它。我试图寻找有关clang
错误的其他问题,但它们似乎不适合这个,也许我需要一些非常基本的帮助来了解我应该在哪里解决这个问题。
c - 为什么在 AMD64 上对 mmap 内存的未对齐访问有时会出现段错误?
我有这段代码在兼容 AMD64 的 CPU 上的 Ubuntu 14.04 上运行时会出现段错误:
如果内存是使用分配的,这只会出现段错误mmap
。如果我使用malloc
堆栈上的缓冲区或全局变量,它不会出现段错误。
如果我将循环的迭代次数减少到少于 14 次,则不再出现段错误。如果我从循环中打印数组索引,它也不再出现段错误。
为什么未对齐的内存访问在能够访问未对齐地址的 CPU 上会出现段错误,为什么仅在这种特定情况下?
performance - 为什么“#pragma omp simd”只在 gcc 编译器下的“-O2”中获得很大的性能提升?
检查以下代码:
在我的机器上构建并运行它,它输出:
如果我注释掉“ #pragma omp simd
”,再次构建并运行它:
我们可以看到 " #pragma omp simd
" 并没有获得很大的性能提升。但是如果我添加-O2
选项,则没有“ #pragma omp simd
”:
带“ #pragma omp simd
”:
我们可以看到很大的进步。但如果使用-O3
,则没有“ #pragma omp simd
”:
与“ #pragma omp simd
”:
我们可以再次看到结果相似。
为什么“ ”只在编译器下#pragma omp simd
有很大的性能提升?-O2
gcc
c++ - 为什么内联函数中的循环无法正确自动矢量化?
我正在尝试对一些简单的计算进行矢量化,以加快 SIMD 架构的速度。但是,我也想将它们作为内联函数,因为函数调用和非向量化代码也需要计算时间。但是,我不能总是同时实现它们。事实上,我的大多数内联函数都无法自动矢量化。这是一个有效的简单测试代码:
在 Mac OS X 10.12.3 上,编译它:
但是,非常相似的东西(仅在 call_add1 中移动参数)不起作用:
使用相同的命令编译不会产生任何输出。为什么会这样?如何确保内联函数中的循环始终自动矢量化?我想矢量化许多函数循环,所以我希望修复不会太复杂。
swift - Swift 编译器会自动将循环向量化作为优化吗?
我正在学习并行/分布式计算课程,并且想知道 Swift 编译器是否执行任何自动矢量化来优化循环。我知道 LLVM 执行了很多(全部?)优化。我发现这个页面详细介绍了它的一些自动矢量化优化,它指出它默认是打开的:(https://llvm.org/docs/Vectorizers.html#the-loop-vectorizer)
我想知道这对于 Swift 是否仍然适用,因为它是建立在 LLVM 之上的。这些优化也会发生在 SIL 或 IR 级别吗?我是编译器的新手,所以如果我的理解不正确,请纠正我。谢谢
c - 奇怪的 SSE 输出
从过去的一周开始,我正在研究 SSE 指令和自动矢量化。我有用 C 编写的代码,其中包含在非常大的图像上执行插值的长时间运行循环。下面是骨架代码。
我编写了上面的代码,以便它成功地被 VS 2015 自动矢量化,但矢量化后我没有得到任何性能差异。(这是预期的,因为上述代码的内存访问模式和较少的算术。) 我创建了上述代码的 3 组编译副本,并测试了相同数据的执行速度。下面是结果。
1) 没有矢量化和没有 SSE 开关的测试代码 ==> 速度是 1X。
2) 没有矢量化编译/Arch:SSE2
==> 速度是 10X。
3) 成功自动矢量化所有代码, /Arch:SSE2
==> 速度为 10.5X
第二个副本只是通过启用 SSE2 指令集进行编译,代码根本没有向量化。仅使用 SSE2 开关,性能如何提高 10 倍?没有任何矢量化
注意:我在 Intel I3 上进行了 4 GB 内存和 windows 7 32 位操作系统的测试,我也在 64 位 windows 上测试了代码,结果相似。
c++ - 简单的 getter/accessor 防止矢量化 - gcc 错误?
考虑这个固定的最小实现vector<int>
:
给定以下测试用例:
编译器生成非矢量化程序集:godbolt.org上的实时示例
如果我进行以下任何更改...
values[size()]
->values[_size]
添加
__attribute__((always_inline))
到size()
...然后编译器生成矢量化程序集:godbolt.org上的实时示例
这是一个 gcc 错误吗?或者,除非明确添加,否则是否有一个简单的访问器(例如,size()
会阻止自动矢量化)的原因?always_inline
c++ - 如何编写编译器可以优化到 SIMD 比较的代码?
智能编译器可以很好地编译到 SIMD 上面。但是如何编写像下面这样的比较也可以很好地编译为 SIMD;