我们如何在Vector256(System.Runtime.Intrinsics.X86)中交换字节?

问题描述 投票:0回答:1

我正在.net core 3.0中使用新的System.Runtime.Intrinsics.X86命名空间(单指令,多个数据)在c#中优化高斯滤波器。

我正在使用Vector256做为算法的最大部分,但最后我必须进行除法。我发现了如何从Vector256转到2 Vector256以进行区分,但是我很难将其恢复为ushort版本,这样我就可以输出数据了。我正在尝试使用Avx2.PackUnsignedSaturate(vector1,vector2),它有效地给了我一个Vector256,但项目已经混合了(有点字节序,但是每个我的ushort都有单独的值)]

我需要的是在中间交换几个字节。使用常规循环(不带SIMD)将值放回输出中将很容易,但是也浪费时间(嗯,我认为...很难说是否无法对simd解决方案进行基准测试)

-我已经尝试过将Vector256强制转换为字节。我无法实现所需的功能,字节移动似乎仅限于其各自的128位。-我尝试查看MSDN,没有关于这些新功能的示例或描述,因此对于大多数新功能,我不知道它们在做什么-我尝试查看英特尔指南(https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf),尽管它们确实解释了一些内容,但我认为我需要的那些内容(也许是XCHG或BSWAP?)在命名空间中找不到它们。

var initialVector1 = System.Runtime.Intrinsics.Vector256.Create(1, 2, 3, 4, 5, 6, 7, 8);
var initialVector2 = System.Runtime.Intrinsics.Vector256.Create(9, 10, 11, 12, 13, 14, 15, 16);

var convertedBackToUshort = Avx2.PackUnsignedSaturate(initialVector1, initialVector2);

convertedBackToUshort的内容应为:1,2,3,4,5,6,7,8,9,10,11,12, 13,14,15,16

但是我得到了:1,2,3,4,9,10,11,12,5,5,6,7,8, 13,14,15,16

使用Avx2.Shuffle(convertedBackToUshort, mask),我无法将9重新带回右侧(尝试使用多个for循环来“强行将面罩强行拉开”)

c# .net-core simd intrinsics
1个回答
0
投票

Avx2.PackUnsignedSaturate aka VPACKUSWB / VPACKUSDW,就像许多256位操作一样,可以并排使用两个128位版本的操作,而不是像128位版本的放大版本。有一个漂亮的图像on this page。也有跨车道洗牌,例如Avx2.Permute4x64,您可以根据需要将其按“自然”顺序放置。它需要一个Vector256<UInt64>,但这并不重要,只需在前后前后重新解释向量即可。使用标量循环确实不会高效,这不仅是因为它是一个标量循环,而且还因为在向量和“标量束”之间进行转换会产生开销。

此问题中存在一个更深层次的问题,因为高斯滤波器(或实际上通常是任何卷积)通常不包含除法运算,因此最终不需要此步骤。由于您的数据是超短裤,因此您可以使用Avx2.MultiplyHigh缩放0到1之间的倍数,而无需执行任何复杂的操作。

© www.soinside.com 2019 - 2024. All rights reserved.