标签: simd

将两个x86 32位寄存器存储到128位xmm寄存器中

有没有更快的方法在一个128位xmm寄存器中存储两个x86 32位寄存器?

  movd  xmm0, edx
  movd  xmm1, eax
  pshufd xmm0, xmm0, $1
  por   xmm0, xmm1 
Run Code Online (Sandbox Code Playgroud)

因此,如果EAX为0x12345678且EDX为0x87654321,则xmm0中的结果必须为0x8765432112345678.

谢谢

x86 assembly sse simd

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

如何比较__m128类型?

__m128 a;
__m128 b;
Run Code Online (Sandbox Code Playgroud)

如何编码a != b

用什么:_mm_cmpneq_ps_mm_cmpneq_ss

如何处理结果?

找不到足够的文档.

x86 sse simd

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

SSE比FPU慢?

我有一大段代码,其中一部分包含这段代码:

result = (nx * m_Lx + ny * m_Ly + m_Lz) / sqrt(nx * nx + ny * ny + 1);
Run Code Online (Sandbox Code Playgroud)

我已经矢量化如下(一切都已经是float):

__m128 r = _mm_mul_ps(_mm_set_ps(ny, nx, ny, nx),
                      _mm_set_ps(ny, nx, m_Ly, m_Lx));
__declspec(align(16)) int asInt[4] = {
    _mm_extract_ps(r,0), _mm_extract_ps(r,1),
    _mm_extract_ps(r,2), _mm_extract_ps(r,3)
};
float (&res)[4] = reinterpret_cast<float (&)[4]>(asInt);
result = (res[0] + res[1] + m_Lz) / sqrt(res[2] + res[3] + 1);
Run Code Online (Sandbox Code Playgroud)

结果是正确的; 但是,我的基准测试显示矢量化版本较慢:

  • 非矢量化版本需要3750毫秒
  • 矢量化版本需要4050毫秒
  • 设置result0直接(和完全除去这部分代码)降低了整个过程至2500毫秒

鉴于矢量版本只包含一个集SSE乘法(而不是四个单独的FPU乘法)的,为什么会慢?FPU确实比SSE快,或者这里有混淆变量吗?

(我在移动Core i5上.)

c++ optimization sse simd vectorization

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

使用SSE对数,还是切换到FPU?

我正在做一些统计计算.我需要它们快速,所以我重写了大部分内容以使用SSE.我对它很陌生,所以我想知道这里的正确方法是什么:

据我所知,SSE中没有log2或ln功能,至少不能达到4.1,这是我使用的硬件支持的最新版本.

是否更好:

  1. 提取4个浮点数,并对它们进行FPU计算以确定它是否具有熵 - 我不需要将任何这些值加载回SSE寄存器,只需将它们加到另一个浮点数中
  2. 找到执行log2的SSE函数

sse logarithm simd natural-logarithm

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

在x86 SIMD向量中查找最大元素的索引

我正在考虑为uint32_t实现8-ary heapsort.为此,我需要一个函数来选择8元素向量中的最大元素的索引,以便我可以将它与父元素进行比较,并有条件地执行swap和进一步的siftDown步骤.

(8 uint32_ts可以更改为例如16 uint32_ts或8 uint64_t或x86 SIMD可以有效支持的任何内容).

我有一些关于如何做到这一点的想法,但我正在寻找比非矢量化代码更快的东西,特别是我正在寻找一些能让我快速进行快速操作的东西.

我有clang ++ 3.3和Core i7-4670,所以我应该能够使用最新的x86 SIMD东西.

(顺便说一下:这是一个更大项目的一部分:https://github.com/tarsa/SortingAlgorithmsBenchmark,例如四元heapsort,所以在实施SIMD heapsort后我可以立即比较它们)

重复 - 问题是:计算x86 SIMD向量中最大元素索引的最有效方法什么?

PS:这不是链接问题的重复 - 注意我要求的是最大元素的索引,而不仅仅是元素值.

c++ x86 sse simd avx

9
推荐指数
2
解决办法
3802
查看次数

通过线程和SIMD并行化矩阵乘法

我正在尝试加速多核架构上的矩阵乘法.为此,我尝试同时使用线程和SIMD.但我的结果并不好.我通过顺序矩阵乘法测试加速:

void sequentialMatMul(void* params)
{
    cout << "SequentialMatMul started.";
    int i, j, k;
    for (i = 0; i < N; i++)
    {
        for (k = 0; k < N; k++)
        {
            for (j = 0; j < N; j++)
            {
                X[i][j] += A[i][k] * B[k][j];
            }
        }
    }
    cout << "\nSequentialMatMul finished.";
}
Run Code Online (Sandbox Code Playgroud)

我尝试将线程和SIMD添加到矩阵乘法中,如下所示:

void threadedSIMDMatMul(void* params)
{
    bounds *args = (bounds*)params;
    int lowerBound = args->lowerBound;
    int upperBound = args->upperBound;
    int idx = args->idx;

    int i, j, k;
    for (i …
Run Code Online (Sandbox Code Playgroud)

c performance multithreading simd matrix-multiplication

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

在通用Windows平台中使用Vector <T>进行SIMD

我正在尝试使用System.Numerics.Vector(T)来矢量化算法并利用CPU的SIMD操作.但是,我的矢量实现比我原来的实现要慢得多.有没有使用可能没有记录的Vector的技巧?这里的具体用途是尝试加速数据的kb.

不幸的是,我在其上找到的几乎所有文档都基于RyuJIT的预发布版本,我不知道有多少这些材料可以移植到.NET Native.

当我在Vector xor操作期间检查反汇编时,它显示:

00007FFB040A9C10  xor         eax,eax  
00007FFB040A9C12  mov         qword ptr [rcx],rax  
00007FFB040A9C15  mov         qword ptr [rcx+8],rax  
00007FFB040A9C19  mov         rax,qword ptr [r8]  
00007FFB040A9C1C  xor         rax,qword ptr [rdx]  
00007FFB040A9C1F  mov         qword ptr [rcx],rax  
00007FFB040A9C22  mov         rax,qword ptr [r8+8]  
00007FFB040A9C26  xor         rax,qword ptr [rdx+8]  
00007FFB040A9C2A  mov         qword ptr [rcx+8],rax  
00007FFB040A9C2E  mov         rax,rcx  
Run Code Online (Sandbox Code Playgroud)

为什么不使用xmm寄存器和SIMD指令呢?同样奇怪的是,SIMD指令是针对此代码的一个版本生成的,我没有明确地向量化,但它们从未被执行,有利于常规寄存器和指令.

我确保我在Release,x64,Optimize代码启用的情况下运行.我看到了x86编译的类似行为.我在机器级别的东西上有点新手,所以它可能只是在这里发生了一些我不能正确理解的东西.

Framework版本为4.6,Vector.IsHardwareAccelerated在运行时为false.

更新: "使用.NET Native工具链编译"是罪魁祸首.启用它会导致Vector.IsHardwareAccelerated == false; 禁用它会导致Vector.IsHardwareAccelerated == true.我已经确认,当禁用.NET Native时,编译器会使用ymm寄存器生成AVX指令.这导致了一个问题......为什么在.NET Native中没有启用SIMD?有什么办法可以改变吗?

更新Tangent:我发现自动SSE矢量化数组代码未被执行的原因是因为编译器插入了一条指令,该指令查看数组的起始位置是否低于最后一个元素之一的地址数组,如果是,只使用普通寄存器.我认为这必定是编译器中的一个错误,因为按照惯例,数组的开头应始终位于比其最后一个元素低的地址.它是测试每个操作数数组的内存地址的一组指令的一部分,我想确保它们不重叠.我已为此提交了Microsoft Connect错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/1831117

.net assembly simd .net-native uwp

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

如何指示编译器为__m128生成未对齐的载荷

我有一些适用于__m128值的代码.我在这些值上使用x86-64 SSE内在函数,我发现如果值在内存中未对齐,我会崩溃.这是由于我的编译器(在此实例中为clang)仅生成对齐的加载指令.

我是否可以指示我的编译器生成未对齐的加载,无论是全局加载还是某些值(可能带有某种注释)?


我首先得到未对齐值的原因是我试图节省内存.我有一个struct大致如下:

#pragma pack(push, 4)
struct Foobar {
    __m128 a;
    __m128 b;
    int c;
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

然后我创建了这些结构的数组.数组中的第二个元素从36个字节开始,这不是16的倍数.

我知道我可以切换到数组表示的结构,或者删除打包编译指示(代价是将结构的大小从36增加到48字节); 但我也知道,未对齐的载荷现在并不那么昂贵,并且想先尝试一下.


更新以回答以下一些评论:

我的实际代码更接近于此:

struct Vector4 {
    __m128 data;
    Vector4(__m128 v) : data(v) {}
};
struct Foobar {
    Vector4 a;
    Vector4 b;
    int c;
}
Run Code Online (Sandbox Code Playgroud)

然后我有一些实用功能,例如:

inline Vector4 add( const Vector4& a, const Vector4 &b ) {
    return Vector4(_mm_add_ps(a.data, b.data));
}

inline Vector4 subtract( const Vector4& a, const Vector4& b ) {
    return Vector4(_mm_sub_ps(a.data, b.data));
} …
Run Code Online (Sandbox Code Playgroud)

c++ sse x86-64 simd intrinsics

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

浏览器JavaScript是否允许SIMD或矢量化操作?

我想用JavaScript编写需要大量数值计算的应用程序.但是,我对客户端JavaScript中有效的线性代数式计算的状态非常困惑.似乎有很多方法,但没有明确表明他们的准备情况.它们中的大多数似乎都限制了允许计算的向量和矩阵的大小.

WebGL的

显然允许GPU上的矢量和矩阵计算,但我不清楚其局限性.围绕此库尝试的 包装器似乎限制了矩阵和向量的大小.这是一个实际的限制(浏览器不支持其他任何东西)或只是开发限制(有人需要编写代码)?

WebCL

WebCL是OpenCL的一个提议的浏览器级实现,但似乎停留在开发中.

WebGPU

Apple最近提出了一种名为WebGPU的 WebCL替代方案.到目前为止,有一个原型和演示,但我不清楚这是否会被广泛采用.

SIMD

Mozilla已经推出了一个用于SIMD操作的API,但它只有实验支持.

JavaScript支持浏览器端的矢量化计算吗?


笔记:

  • 我的问题不是"JavaScript中的数值计算有什么好的库",而是"JavaScrpt中的矢量化操作是否可行?" 可接受的答案将链接到在非实验性浏览器中工作的矢量化计算的演示.

  • 我可能会对SIMD,矢量化和GPU计算感到困惑.我认为在这种情况下同义地使用它们是可以的,因为它们都允许通过使用专门的计算机硬件进行涉及高维向量的有效计算.

javascript vector simd matrix vectorization

9
推荐指数
2
解决办法
1505
查看次数

Constexpr和SSE内在函数

大多数C++编译器都支持SIMD(SSE/AVX)指令

_mm_cmpeq_epi32
Run Code Online (Sandbox Code Playgroud)

我的问题是这个函数没有标记为constexpr,虽然"语义上"没有理由不使用这个函数,constexpr因为它是一个纯函数.

有什么办法,我可以写我自己的版本(例如)_mm_cmpeq_epi32constexpr

显然我希望运行时的函数使用正确的asm,我知道我可以重新实现具有慢速函数的任何SIMD函数constexpr.

如果你想知道为什么我关心constexprSIMD功能.非constexprness具有传染性,这意味着我的任何使用SIMD功能的功能都不可能constexpr.

c++ sse simd intrinsics constexpr

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