标签: simd

将3D数学转换为SSE或其他SIMD需要多少加速?

我在我的应用程序中广泛使用3D数学.通过将矢量/矩阵库转换为SSE,AltiVec或类似的SIMD代码,我可以实现多少加速?

optimization x86 sse native simd

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

SSE2:双精度日志功能

我需要开源(没有许可限制)日志功能的实现,有签名的东西

__m128d _mm_log_pd(__m128d);
Run Code Online (Sandbox Code Playgroud)

它可以在英特尔短矢量数学库(ICC的一部分)中使用,但ICC既不是免费的也不是开源的.我正在寻找仅使用内在函数的实现.

它应该使用特殊的有理函数近似.我需要的东西几乎与cmath日志一样准确,比如9-10十进制数字,但更快.

c c++ optimization sse simd

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

SSE微优化指令顺序

我注意到有时MSVC 2010根本没有重新排序SSE指令.我认为我不必关心循环中的指令顺序,因为编译器处理的最好,但似乎并非如此.

我该怎么想这个?什么决定最佳指令顺序?我知道某些指令具有比其他指令更高的延迟,并且某些指令可以在cpu级别上并行/异步运行.哪些指标与上下文相关?我在哪里可以找到它们?

我知道我可以通过剖析来避免这个问题,但是这些剖析器很昂贵(VTune XE)并且我想知道它背后的理论,而不仅仅是经验结果.

我也应该关心软件预取(_mm_prefetch)还是我可以假设cpu会比我做得更好?

可以说我有以下功能.我应该交错一些指令吗?我应该在流之前做商店,按顺序做所有的负载,然后做计算等......?我是否需要考虑USWC与非USWC,以及时间与非时间?

            auto cur128     = reinterpret_cast<__m128i*>(cur);
            auto prev128    = reinterpret_cast<const __m128i*>(prev);
            auto dest128    = reinterpret_cast<__m128i*>(dest;
            auto end        = cur128 + count/16;

            while(cur128 != end)            
            {
                auto xmm0 = _mm_add_epi8(_mm_load_si128(cur128+0), _mm_load_si128(prev128+0));
                auto xmm1 = _mm_add_epi8(_mm_load_si128(cur128+1), _mm_load_si128(prev128+1));
                auto xmm2 = _mm_add_epi8(_mm_load_si128(cur128+2), _mm_load_si128(prev128+2));
                auto xmm3 = _mm_add_epi8(_mm_load_si128(cur128+3), _mm_load_si128(prev128+3));

                                    // dest128 is USWC memory
                _mm_stream_si128(dest128+0, xmm0);  
                _mm_stream_si128(dest128+1, xmm1);
                _mm_stream_si128(dest128+2, xmm2);;
                _mm_stream_si128(dest128+3, xmm3);

                                    // cur128 is temporal, and will be used next time, which …
Run Code Online (Sandbox Code Playgroud)

c++ optimization sse simd micro-optimization

10
推荐指数
3
解决办法
2045
查看次数

C#矢量化阵列加法

无论如何以SIMD方式"向量化"跨数组的元素添加?

例如,我想转:

var a = new[] { 1, 2, 3, 4 };
var b = new[] { 1, 2, 3, 4 };
var c = new[] { 1, 2, 3, 4 };
var d = new[] { 1, 2, 3, 4 };

var e = new int[4];

for (int i = 0; i < a.Length; i++)
{
    e[i] = a[i] + b[i] + c[i] + d[i];
}

// e should equal { 4, 8, 12, 16 }
Run Code Online (Sandbox Code Playgroud)

变成这样的东西:

var e …
Run Code Online (Sandbox Code Playgroud)

.net c# simd vectorization

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

测试两个__m128i变量之间的相等性

如果我想在两个__m128i变量之间进行逐位相等测试,我是否需要使用SSE指令或者我可以使用==?如果没有,我应该使用哪条SSE指令?

c x86 sse simd

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

检查所有__m128i组件是否为0的最有效方法[使用SSE内在函数]

我正在使用SSE内在函数来确定矩形(由四个int32值定义)是否已更改:

__m128i oldRect; // contains old left, top, right, bottom packed to 128 bits
__m128i newRect; // contains new left, top, right, bottom packed to 128 bits

__m128i xor = _mm_xor_si128(oldRect, newRect);
Run Code Online (Sandbox Code Playgroud)

此时,xor如果矩形未更改,则结果值将全为零.那么最有效的方法是什么呢?

目前我这样做:

if (xor.m128i_u64[0] | xor.m128i_u64[1])
{
    // rectangle changed
}
Run Code Online (Sandbox Code Playgroud)

但我认为有一种更聪明的方法(可能使用了一些我还没有找到的SSE指令).

我在x64上定位SSE4.1,我在Visual Studio 2013中编写C++.

c++ integer sse simd intrinsics

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

实用的BigNum AVX/SSE可能吗?

SSE/AVX寄存器可以被视为整数或浮点BigNums.也就是说,人们可以忽视存在通道.是否有一种简单的方法可以利用这种观点并将这些寄存器单独或组合用作BigNum?我问,因为我从BigNum库中看到的很少,它们几乎普遍存储并对数组进行算术运算,而不是SSE/AVX寄存器.可移植性?

例:

假设您将SSE寄存器的内容存储为a中的键std::set,您可以将这些内容作为BigNum进行比较.

sse simd biginteger avx extended-precision

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

C++为SIMD设计:使SoA不再是PiTA

苦乐参半的SoAs

我最近看到了使用手工编写的SIMD内在函数与SoA(数组结构)表示的乐趣.

与我之前的AoS(结构阵列)代码相比,速度的改进,至少对于简单的顺序型流媒体操作而言,在加倍到三倍的速度增加时几乎没有什么惊人的.作为奖励,它简化了逻辑,除了减少内存使用外,还排除了那些棘手的水平操作和混乱组件.

然而,之后有这种苦乐参半的感觉,我意识到他们在代码中使用的是什么PITA,尤其是界面设计.

中级接口设计

我经常处理设计中级接口.它们比视频游戏中的级别更高std::vector,但比级别更低Monster.这些对我来说总是一些最笨拙的接口设计和保持稳定,因为它们不足以提供与标准C++容器一样的简单读/写接口.然而,它们不够高级(在界面的入口点缺乏足够的逻辑)来完全隐藏和抽象出底层表示,只提供高级操作.

我认为中级设计的一个例子是可编程粒子系统API,它希望在某些场景下尽可能高效和可扩展,同时便于休闲场景(例如脚本编写者).这样的设计必须提供粒子访问,除非它将为每个可能的算法提供与可想象的粒子相关的方法,否则它必须在某个地方暴露一些原始的SoA细节,让客户从中受益.

设计也不一定要求始终写入SoA类型代码.日常使用量越多,对便利性,简单性,生产率的要求仍然不高.它仅适用于那些罕见的,性能关键的场景,其中底层的SoA表示派上用场.

那么API/lib设计师和大型系统人员如何处理这些需求的平衡呢?

平衡多种访问模式

由于SoA消除了任何每个元素的结构,因此当用户nth使用接口的更方便的随机访问部分访问元素时,动态实例化结构/类可能是一个不错的主意吗?也许一个结构包含指向多个SoA数组的第n个条目的指针/引用以进行可变访问?

此外,如果更常见的使用模式是更多随机访问标量逻辑而不是顺序访问SIMD向量逻辑,但SIMD部分被触发足以使其更好地仅使用一个数据结构,可能这种混合SoA表示更好地平衡了所有需求?

struct AoSoA
{
    ALIGN16 float x[4];
    ALIGN16 float y[4];
    ALIGN16 float z[4];
};
ALIGN16 AoSoA elements[n/4];
Run Code Online (Sandbox Code Playgroud)

我不明白高速缓存行的本质,以便知道这种表示是否值得.我注意到它对顺序SIMD情况没有多大帮助,我们可以将全部资源用于一个庞大的算法,但似乎它可能对需要跨组件或随机访问的大量水平逻辑的情况有帮助标量逻辑情况,系统可能同时执行许多其他操作.

无论如何,我一般都在寻求深入了解如何有效地设计具有SoA后端表示的中间层数据结构接口作为实现细节,而不会将复杂性转移到客户端,除非他们真的需要它.

我真的想避免强迫客户端总是在每个使用界面的地方编写SoA类型的代码,除非他们确实需要这种效率,我很好奇如何平衡那些更多的日常随机访问标量使用场景与利用SoA表示的罕见但不太常见的场景.

c++ architecture optimization simd

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

两个256位整数的按位xor

我有一个AVX CPU(不支持AVX2),我想计算两个256位整数的按位xor.

由于_mm256_xor_si256仅在AVX2上可用,我可以将这256位加载为__m256使用_mm256_load_ps,然后执行a _mm256_xor_ps.这会产生预期的结果吗?

我主要担心的是,如果内存内容不是有效的浮点数,_mm256_load_ps那么寄存器中的位不会与寄存器中的位完全相同吗?

谢谢.

sse simd avx

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

为多个SIMD架构生成代码

我编写了一个库,我使用CMake来验证MMX,SSE,SSE2,SSE4,AVX,AVX2和AVX-512的标头是否存在.除此之外,我检查是否存在指令,如果存在,我添加必要的编译器标志,-msse2 -mavx -mfma等.

这一切都非常好,但我想部署一个二进制文件,它适用于各代处理器.

问题:是否有可能告诉编译器(GCC)每当使用SIMD优化函数时,它必须为架构列表生成代码?当然还有高级分支机构

我在想类似于编译器如何为函数生成代码,其中输入指针是4或8字节对齐的.为了防止这种情况,我使用__builtin_assume_aligned宏.

什么是最佳做法?多个二进制文件?命名?

gcc simd avx sse4

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