相关疑难解决方法(0)

使用AVX CPU指令:没有"/ arch:AVX"的性能不佳

我的C++代码使用SSE,现在我想改进它以支持AVX可用时.所以我检测AVX何时可用并调用使用AVX命令的函数.我使用Win7 SP1 + VS2010 SP1和带AVX的CPU.

要使用AVX,必须包含以下内容:

#include "immintrin.h"
Run Code Online (Sandbox Code Playgroud)

然后你可以使用内在的AVX函数_mm256_mul_ps,_mm256_add_ps等等.问题是,默认情况下,VS2010产生的代码工作得非常慢,并显示警告:

警告C4752:发现英特尔(R)高级矢量扩展; 考虑使用/ arch:AVX

似乎VS2010实际上不使用AVX指令,而是模仿它们.我添加/arch:AVX到编译器选项并获得了良好的结果.但是这个选项告诉编译器尽可能在任何地方使用AVX命令.所以我的代码可能会崩溃在不支持AVX的CPU上!

所以问题是如何使VS2010编译器生成AVX代码,但只有当我直接指定AVX内在函数时.对于它工作的SSE,我只使用SSE内在函数,它产生SSE代码,没有任何编译器选项,如/arch:SSE.但对于AVX而言,由于某些原因它不起作用.

c++ performance sse visual-studio-2010 avx

49
推荐指数
2
解决办法
3万
查看次数

在x86上做水平浮点矢量和的最快方法

你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?

SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?

"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)

floating-point optimization x86 assembly sse

41
推荐指数
4
解决办法
2万
查看次数

不同的mmx,sse和avx版本是互补的还是互补的?

我想我应该熟悉x86 SIMD扩展.但在我开始之前,我遇到了麻烦.我无法找到关于哪些仍然相关的良好概述.

几十年来,x86架构积累了大量的数学/多媒体扩展:

  • MMX
  • 支持3DNow!
  • SSE
  • SSE2
  • SSE3
  • SSSE3
  • SSE4
  • AVX
  • AVX2
  • AVX512
  • 我忘记了什么吗?

较新的超集是旧的超集,反之亦然?或者它们是互补的吗?

有些人已被弃用吗?哪些仍然相关?我听说过"遗留SSE".

有些是互斥的吗?即他们共享相同的硬件部分?

我应该一起使用哪个来最大化现代Intel/AMD CPU的硬件利用率?为了争论,让我们假设我可以找到适当的指令用途...如果没有别的话,用CPU加热我的房子.

x86 sse avx mmx

20
推荐指数
2
解决办法
4838
查看次数

在现代x86上有哪些方法可以有效地扩展指令长度?

想象一下,您希望将一系列x86汇编指令与某些边界对齐.例如,您可能希望将循环对齐到16或32字节的边界,或者将指令打包以使它们有效地放置在uop缓存中或其他任何位置.

实现这一目标的最简单方法是单字节NOP指令,紧接着是多字节NOP.虽然后者通常效率更高,但这两种方法都不是免费的:NOP使用前端执行资源,并且还计入现代x86上的4宽1重命名限制.

另一个选择是以某种方式延长一些指令以获得所需的对齐.如果这样做没有引入新的停顿,它似乎比NOP方法更好.如何在最近的x86 CPU上有效地延长指令?

在理想的世界中,延长技术同时是:

  • 适用于大多数说明
  • 能够通过可变数量延长指令
  • 不会停止或以其他方式减慢解码器的速度
  • 在uop缓存中有效表示

有一种方法不可能同时满足所有上述要点,因此很好的答案可能会解决各种权衡问题.


1 AMD Ryzen的限制为5或6.

optimization performance x86 assembly micro-optimization

20
推荐指数
1
解决办法
683
查看次数

动态确定恶意AVX-512指令的执行位置

我有一个在支持AVX-512的Intel机器上运行的进程,但是这个进程不直接使用任何AVX-512指令(asm或内在函数)并且编译时-mno-avx512f使编译器不插入任何AVX-512指令.

然而,它在减少的AVX turbo频率下无限运行.毫无疑问,有一个AVX-512指令在某个地方偷偷摸摸,通过一个库,(非常不可能)系统调用或类似的东西.

而不是尝试"二进制搜索"AVX-512指令来自哪里,有没有什么方法可以立即找到它,例如,捕获这样的指令?

操作系统是Ubuntu 16.04.

linux performance x86 intel avx512

15
推荐指数
1
解决办法
648
查看次数

SIMD指令降低CPU频率

我读了这篇文章。它谈到了为什么AVX-512指令:

英特尔最新的处理器具有高级指令(AVX-512),这可能会导致内核或其他CPU的运行速度变慢,这是因为它们使用了多少电量。

我认为在Agner的博客上也提到了类似的内容(但我找不到确切的帖子)。

我想知道Skylake支持的其他哪些指令会产生类似的效果,即它们会降低功耗以在以后最大化吞吐量吗?所有前缀v指令(如vmovapdvmulpdvaddpdvsubpdvfmadd213pd)?

我正在尝试编译说明列表,以避免在为Xeon Skylake编译C ++应用程序时避免。

optimization x86 intel compiler-optimization avx512

12
推荐指数
2
解决办法
564
查看次数

一个更好的8x8字节矩阵转置与SSE?

我发现这个职位,说明如何进行转一个8x8矩阵的字节24点的操作,和几个卷轴后有代码实现转置.但是,这种方法没有利用我们可以阻止 8x8转置为4个4x4转置的事实,并且每个转换只能在一个shuffle指令中完成(这篇文章是参考文献).所以我推出了这个解决方案:

__m128i transpose4x4mask = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13,  9, 5, 1, 12,  8, 4, 0);
__m128i shuffle8x8Mask = _mm_setr_epi8(0, 1, 2, 3, 8, 9, 10, 11, 4,  5, 6, 7, 12,  13, 14, 15);

void TransposeBlock8x8(uint8_t *src, uint8_t *dst, int srcStride, int dstStride) {
    __m128i load0 = _mm_set_epi64x(*(uint64_t*)(src + 1 * srcStride), *(uint64_t*)(src + 0 * srcStride));
    __m128i load1 = _mm_set_epi64x(*(uint64_t*)(src + 3 * srcStride), *(uint64_t*)(src + …
Run Code Online (Sandbox Code Playgroud)

c optimization sse simd matrix

11
推荐指数
1
解决办法
1273
查看次数

可以在同一代码路径中混合传统SSE编码指令和VEX编码指令吗?

随着AVX的推出,英特尔将VEX编码方案引入了英特尔64和IA-32架构.该编码方案主要用于AVX指令.我想知道是否可以混合使用VEX编码指令和现在称为"传统SSE"的指令.

我问这个问题的主要原因是代码大小.请考虑以下两条说明:

shufps xmm0, xmm0, 0
vshufps xmm0, xmm0, xmm0, 0
Run Code Online (Sandbox Code Playgroud)

我通常使用第一个"广播"标量值到XMM寄存器中的所有位置.现在,指令集表明这两者之间的唯一区别(在这种情况下)是VEX编码的一个清除了YMM寄存器的高位(> = 128).假设我不需要,在这种情况下使用VEX编码版本有什么好处?第一条指令需要4个字节(0FC6C000),第二条指令需要5个(C5F8C6C000).

提前感谢所有答案.

x86 assembly sse avx

10
推荐指数
1
解决办法
974
查看次数

使用AVX后,SSE运行缓慢

我有一些奇怪的问题,我正在研究一些SSE2和AVX代码.我正在使用GCC构建我的应用程序,运行时cpu特征检测.对象文件使用每个CPU功能的单独标志构建,例如:

g++ -c -o ConvertSamples_SSE.o ConvertSamples_SSE.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -msse
g++ -c -o ConvertSamples_SSE2.o ConvertSamples_SSE2.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -msse2
g++ -c -o ConvertSamples_AVX.o ConvertSamples_AVX.cpp -std=c++11 -fPIC -O0 -g -Wall -I./include -mavx
Run Code Online (Sandbox Code Playgroud)

当我第一次启动该程序时,我发现SSE2例程正常,非SSE例程的速度提升(大约快100%).在我运行任何AVX例程之后,完全相同的SSE2例程现在运行得慢得多.

有人可以解释一下这可能是什么原因吗?

在AVX例程运行之前,所有测试都比FPU数学运算快大约80-130%,如此处所示,在AVX例程运行之后,SSE例程要慢得多.

如果我跳过AVX测试程序,我从未看到这种性能损失.

这是我的SSE2例程

void Float_S16(const float *in, int16_t *out, const unsigned int samples)
{
  static float  ratio = (float)Limits<int16_t>::range() / (float)Limits<float>::range();
  static __m128 mul   = _mm_set_ps1(ratio);

  unsigned int i;
  for (i = 0; i < samples - 3; i += 4, …
Run Code Online (Sandbox Code Playgroud)

c++ x86 gcc avx sse2

10
推荐指数
1
解决办法
762
查看次数

如果您的程序+库不包含SSE指令,那么使用VZEROUPPER是否有用?

我理解VZEROUPPER在混合SSE和AVX代码时使用很重要,但如果我只使用AVX(和普通的x86-64代码)而不使用任何传统的SSE指令呢?

如果我从不在我的代码中使用单个SSE指令,是否有任何性能原因我需要使用VZEROUPPER

这假设我没有调用任何外部库(可能使用SSE).

performance x86 assembly avx micro-optimization

9
推荐指数
1
解决办法
413
查看次数