相关疑难解决方法(0)

使用AVX指令进行水平矢量和的最快方法

我有一个四个64位浮点值的打包向量.
我想得到向量元素的总和.

使用SSE(并使用32位浮点数),我可以执行以下操作:

v_sum = _mm_hadd_ps(v_sum, v_sum);
v_sum = _mm_hadd_ps(v_sum, v_sum);
Run Code Online (Sandbox Code Playgroud)

不幸的是,即使AVX具有_mm256_hadd_pd指令,它的结果也与SSE版本不同.我相信这是因为大多数AVX指令分别用作每个低128位和高128位的SSE指令,而不会跨越128位边界.

理想情况下,我要寻找的解决方案应遵循以下准则:
1)仅使用AVX/AVX2指令.(没有SSE)
2)不超过2-3条指令.

但是,任何有效/优雅的方式(即使不遵循上述指导原则)总是被广泛接受.

非常感谢您的帮助.

-Luigi Castelli

x86 sse simd vector-processing avx

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

AVX2:计算 512 个浮点数组的点积

我先说我是 SIMD 内在函数的完全初学者。

本质上,我有一个支持 AVX2 内在 ( Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz)的 CPU 。我想知道计算两个std::vector<float>size的点积的最快方法512

我在网上做了一些挖掘,发现了这个这个这个堆栈溢出问题建议使用以下函数__m256 _mm256_dp_ps(__m256 m1, __m256 m2, const int mask);,但是,这些都表明了执行点积的不同方法我不确定什么是正确的(和最快的)方法它。

特别是,我正在寻找对大小为 512 的向量执行点积的最快方法(因为我知道向量大小会影响实现)。

感谢您的帮助

编辑 1:我也对-mavx2gcc 标志有点困惑。如果我使用这些 AVX2 函数,我编译时是否需要添加标志?另外,-OFast如果我编写了一个天真的点积实现,gcc 是否能够为我做这些优化(比如我使用gcc 标志)?

编辑 2 如果有人有时间和精力,如果您能编写完整的实现,我将不胜感激。我相信其他初学者也会重视这些信息。

c++ simd dot-product avx2 fma

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

如何在256位AVX向量中找到水平最大值

我有一个__m256d向量,包含四个64位浮点值.
我需要找到向量元素的水平最大值,并将结果存储在双精度标量值中;

我的尝试最终都使用了很多矢量元素的改组,使得代码不是很优雅也没有效率.此外,我发现不可能只留在AVX域.在某些时候,我不得不使用SSE 128位指令来提取最终的64位值.但是,我想在最后的声明中被证明是错误的.

因此理想的解决方案将:
1)仅使用AVX指令.
2)最小化指令数量.(我希望不超过3-4条说明)

话虽如此,任何优雅/高效的解决方案都将被接受,即使它不符合上述指导原则.

谢谢你的帮助.

-Luigi

x86 simd vector-processing avx avx2

14
推荐指数
2
解决办法
6709
查看次数

使用英特尔上的SSE2减少无溢出的无符号字节数

我试图在Intel i3处理器上找到32个元素(每个1字节数据)的总和减少量.我这样做了:

s=0; 
for (i=0; i<32; i++)
{
    s = s + a[i];
}  
Run Code Online (Sandbox Code Playgroud)

但是,由于我的应用程序是一个需要更少时间的实时应用程序,因此需要花费更多时间.请注意,最终金额可能超过255.

有没有办法可以使用低级SIMD SSE2指令实现这一点?不幸的是我从未使用过SSE.我试图为此目的搜索sse2函数,但它也不可用.(sse)是否可以保证减少这种小型问题的计算时间?

有什么建议??

注意:我已经使用OpenCL和CUDA实现了类似的算法,虽然问题规模很大,但效果很好.对于小型问题,开销成本更高.不确定它在SSE上是如何工作的

x86 sse simd sse2 sse3

13
推荐指数
2
解决办法
4952
查看次数

使用SSE获取__m128i向量中的最大值?

我刚刚开始使用SSE,我很困惑如何获得a的最大整数值(max)__m128i.例如:

__m128i t = _mm_setr_ps(0,1,2,3);
// max(t) = 3;
Run Code Online (Sandbox Code Playgroud)

搜索引导我去MAXPS指导,但我似乎无法找到如何使用它"xmmintrin.h".

此外,是否有任何"xmmintrin.h"您建议的文档,而不是查看头文件本身?

c x86 assembly sse

12
推荐指数
4
解决办法
1万
查看次数

为什么英特尔公布的一些Haswell AVX延迟比Sandy Bridge慢3倍?

在英特尔内部网络应用程序中,从Sandy Bridge到Haswell的几项操作似乎已经恶化.例如,许多插入操作(如_mm256_insertf128_si256)显示如下的成本表:

   Performance
 Architecture   Latency   Throughput
 Haswell        3         -
 Ivy Bridge     1         - 
 Sandy Bridge   1         - 
Run Code Online (Sandbox Code Playgroud)

我发现这种差异令人费解.这有什么不同,因为有新的指令可以取代这些或补偿它的东西(哪些)?有谁知道Skylake是否进一步改变了这个模型?

x86-64 intel simd cpu-architecture avx2

12
推荐指数
1
解决办法
1408
查看次数

如何横向汇总__m256?

我想__m256使用AVX指令水平地对矢量的分量求和.在SSE我可以使用

_mm_hadd_ps(xmm,xmm);
_mm_hadd_ps(xmm,xmm);
Run Code Online (Sandbox Code Playgroud)

在向量的第一个组件处获得结果,但这不能与函数(_mm256_hadd_ps)的256位版本一起扩展.

计算__m256向量水平和的最佳方法是什么?

sse vectorization intrinsics avx

11
推荐指数
2
解决办法
6666
查看次数

快速计算两个数组之间的相等字节数

我编写了该函数int compare_16bytes(__m128i lhs, __m128i rhs),以便使用SSE指令比较两个16字节数:该函数返回执行比较后相等的字节数.

现在我想使用上面的函数来比较任意长度的两个字节数组:长度可能不是16字节的倍数,所以我需要处理这个问题.我怎样才能完成下面这个功能的实现?我怎样才能改进下面的功能?

int fast_compare(const char* s, const char* t, int length)
{
    int result = 0;

    const char* sPtr = s;
    const char* tPtr = t;

    while(...)
    {
        const __m128i* lhs = (const __m128i*)sPtr;
        const __m128i* rhs = (const __m128i*)tPtr;

        // compare the next 16 bytes of s and t
        result += compare_16bytes(*lhs,*rhs);

        sPtr += 16;
        tPtr += 16;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

c c++ sse simd sse2

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

如何从AVX寄存器中获取数据?

使用MSVC 2013和AVX 1,我在寄存器中有8个浮点数:

__m256 foo = mm256_fmadd_ps(a,b,c);
Run Code Online (Sandbox Code Playgroud)

现在我要打电话inline void print(float) {...}给所有8个花车.看起来英特尔 AVX内置技术会让这个变得相当复杂:

print(_castu32_f32(_mm256_extract_epi32(foo, 0)));
print(_castu32_f32(_mm256_extract_epi32(foo, 1)));
print(_castu32_f32(_mm256_extract_epi32(foo, 2)));
// ...
Run Code Online (Sandbox Code Playgroud)

但MSVC甚至没有这两种内在函数.当然,我可以将值写回内存并从那里加载,但我怀疑在汇编级别没有必要溢出寄存器.

奖金问:我当然喜欢写作

for(int i = 0; i !=8; ++i) 
    print(_castu32_f32(_mm256_extract_epi32(foo, i)))
Run Code Online (Sandbox Code Playgroud)

但MSVC并不了解许多内在函数需要循环展开.如何在8x32浮点数上写一个循环__m256 foo

c++ avx visual-c++ fma

11
推荐指数
2
解决办法
4835
查看次数

如何使用C中的SSE内部函数计算矢量点积

我试图将两个向量相乘,其中一个向量的每个元素乘以另一个向量的相同索引中的元素.然后,我想要对结果向量的所有元素求和,以获得一个数字.例如,对于矢量{1,2,3,4}和{5,6,7,8},计算结果如下:

1*5 + 2*6 + 3*7 + 4*8

基本上,我正在采用两个向量的点积.我知道有一个SSE命令来执行此操作,但该命令没有与之关联的内部函数.此时,我不想在我的C代码中编写内联汇编,所以我只想使用内部函数.这似乎是一个常见的计算,所以我很惊讶自己在Google上找不到答案.

注意:我正在针对特定的微架构进行优化,该架构最多支持SSE 4.2.

谢谢你的帮助.

c optimization sse simd vectorization

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