我正在编写一些代码并尝试使用SIMD内在函数SSE2/3来加速它.我的代码具有这样的性质,我需要将一些数据加载到XMM寄存器中并对其进行多次操作.当我查看生成的汇编程序代码时,GCC似乎不断将数据刷新回内存,以便在XMM0和XMM1中重新加载其他内容.我正在编译x86-64所以我有15个寄存器.为什么GCC只使用两个,我该怎么做才能让它使用更多?有什么方法可以"固定"寄存器中的某些值吗?我在我的变量定义中添加了"register"关键字,但生成的汇编代码是相同的.
如何使用GCC提供的Multiply-Accumulate内在函数?
float32x4_t vmlaq_f32 (float32x4_t , float32x4_t , float32x4_t);
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释我必须传递给这个函数的三个参数.我的意思是源和目标寄存器以及函数返回的内容?
救命!!!
如何清除m2的高128位:
__m256i m2 = _mm256_set1_epi32(2);
__m128i m1 = _mm_set1_epi32(1);
m2 = _mm256_castsi128_si256(_mm256_castsi256_si128(m2));
m2 = _mm256_castsi128_si256(m1);
Run Code Online (Sandbox Code Playgroud)
不起作用 - 英特尔针对_mm256_castsi128_si256内在函数的文档说"结果向量的高位未定义".同时我可以在装配中轻松完成:
VMOVDQA xmm2, xmm2 //zeros upper ymm2
VMOVDQA xmm2, xmm1
Run Code Online (Sandbox Code Playgroud)
当然我不想用"和"等等_mm256_insertf128_si256().
我目前正在编写一些针对英特尔即将推出的AVX-512 SIMD指令的代码,该指令支持512位操作.
现在假设有一个由16个SIMD寄存器表示的矩阵,每个寄存器包含16个32位整数(对应一行),如何用纯SIMD指令转置矩阵?
已经有解决方案分别用SSE和AVX2转置4x4或8x8矩阵.但我无法弄清楚如何使用AVX-512将其扩展到16x16.
有任何想法吗?
我想试验SIMD(单指令多数据).从谷歌集团发布的帖子中可以看出,人们一直在努力将其添加到谷歌浏览器中,但当我尝试使用SIMD.Float32x4Chrome 46时,我得到的SIMD未定义.
我的谷歌搜索表明可能有一些Chrome的实验版本具有SIMD支持.什么是包含它的最新版本以及需要设置哪些命令行标志才能使用它?我需要使用严格模式吗?
什么时候SIMD会进入稳定的Chrome版本?
如果运行32位版本的Chrome或64位版本,运行SIMD指令也会有所不同吗?
在R中给出这样的数据帧:
+---+---+
| X | Y |
+---+---+
| 1 | 2 |
| 2 | 4 |
| 4 | 5 |
+---+---+
Run Code Online (Sandbox Code Playgroud)
如果对此数据帧执行矢量化操作,如下所示:
data$Z <- data$X * data$Y
Run Code Online (Sandbox Code Playgroud)
这会利用处理器的单指令多数据(SIMD)功能来优化性能吗?这似乎是一个完美的案例,但我找不到任何证实我的预感的东西.
我正在寻找其他人的代码,目前正试图弄清楚为什么_mm_load_si128存在.
基本上,我尝试更换
_ra = _mm_load_si128(reinterpret_cast<__m128i*>(&cd->data[idx]));
Run Code Online (Sandbox Code Playgroud)
同
_ra = *reinterpret_cast<__m128i*>(&cd->data[idx]);
Run Code Online (Sandbox Code Playgroud)
它的工作原理和表现完全相同.
我认为为了方便起见,较小类型存在加载函数,因此人们不必手动将它们打包到连续内存中,但对于已经按正确顺序排列的数据,为什么要这么麻烦?
还有别的_mm_load_si128吗?或者它本质上只是一种分配价值的迂回方式?
在以下问题是相关的,但答案是旧的,并且从用户评论马克Glisse表明有因为C ++ 17的新方法这个问题可能没有得到充分讨论。
我试图让对齐的内存为 SIMD 正常工作,同时仍然可以访问所有数据。
在 Intel 上,如果我创建一个类型为 的浮点向量__m256,并将我的大小减小 8 倍,它会给我对齐的内存。
例如 std::vector<__m256> mvec_a((N*M)/8);
以一种稍微有点麻烦的方式,我可以将指向向量元素的指针转换为浮点,这允许我访问单个浮点值。
相反,我更喜欢std::vector<float>正确对齐的 ,因此可以加载到__m256其他 SIMD 类型中而不会出现段错误。
我一直在研究aligned_alloc。
这可以给我一个正确对齐的 C 样式数组:
auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));
Run Code Online (Sandbox Code Playgroud)
但是我不确定如何为std::vector<float>. 授予的std::vector<float>所有权marr_a 似乎是不可能的。
我已经看到一些建议我应该编写自定义分配器,但这似乎需要做很多工作,也许现代 C++ 有更好的方法?
我的CPU是AMD Ryzen 7 7840H,支持AVX-512指令集。当我运行.NET8程序时, 的值为Vector512.IsHardwareAcceleratedtrue。但System.Numerics.Vector<T>仍然是256位,并没有达到512位。Vector<T>为什么类型长度没有达到 512 位?目前是否不支持,或者我需要调整配置吗?
示例代码:
TextWriter writer = Console.Out;
writer.WriteLine(string.Format("Vector512.IsHardwareAccelerated:\t{0}", Vector512.IsHardwareAccelerated));
writer.WriteLine(string.Format("Vector.IsHardwareAccelerated:\t{0}", Vector.IsHardwareAccelerated));
writer.WriteLine(string.Format("Vector<byte>.Count:\t{0}\t# {1}bit", Vector<byte>.Count, Vector<byte>.Count * 8));
Run Code Online (Sandbox Code Playgroud)
检测结果:
Vector512.IsHardwareAccelerated: True
Vector.IsHardwareAccelerated: True
Vector<byte>.Count: 32 # 256bit
Run Code Online (Sandbox Code Playgroud) 新的RyuJIT编译器是否曾生成向量(SIMD)CPU指令,何时?
附注:System.Numerics命名空间包含允许显式使用Vector操作的类型,这些操作可能会也可能不会生成SIMD指令,具体取决于CPU,CLR版本,JITer版本,是否直接编译为本机代码.这个问题具体是关于何时非矢量代码(例如在C#或F#中)将产生SIMD指令.