如何使用 AVX2 和 SSE 将较大的整数转换为较小的整数?
使用AVX2和SSE? 例如: int16-> int8 int32-> int16/int32-> int8 int64-> int32/int64-> int16/int64-> int8 我知道AVX-512有说明: VPMOVQB vpmovwb 对应于: 的内在物质 _MM512_CVTEPI16_EPI8(AVX512字节和Word ISA) _MM512_CVTEPI32_EPI8(AVX512基金会) _MM512_CVTEPI32_EPI16(AVX512基金会) _MM512_CVTEPI64_EPI8(AVX512基金会) _MM512_CVTEPI64_EPI16(AVX512基金会) _MM512_CVTEPI64_EPI32(AVX512基金会) 哪种操作整数类型缩小转换率,但是如何在没有这样的说明的AVX2和SSE中完成此操作? 请注意,虽然上述AVX512内在的128和256位过载,但它们仍需要在运
10 2024-04-22
编程技术问答社区
使用 SIMD 移位/旋转字节矢量的最快方法
我有一个AVX2(256位)字节的Simd向量,该向量在前面和后部的零填充,看起来像这样: [0, 2, 3, ..., 4, 5, 0, 0, 0]. 前面的零数量尚不清楚编译时间. 我将如何有效地移动/旋转零,以使其看起来像这样: [2, 3, 4, 5, ..., 0, 0, 0, 0]? 解决方案 avx2无法进行小于4个字节的粒度的车道横断.在这种情况下,您需要AVX-512 VBMI vpermb(在Ice Lake).如果有的话,也许vpcmpeqb/vpmovmskb/tzcnt在掩码上,并将其用作偏移量来从alignas(64) int8_t shuffles = {0,1,2,...,31, 0, 1, 2, ... 31};的常数数组中加载32个字节的窗口.那就是vpermb的shuffle-control矢量. 如果没有AVX-512 VBMI,尽管商店有良好的摊位,但可能会 还是有意义地存放两次并进行了一个不和谐的重新安装.如果您需要在其他许
10 2024-04-22
编程技术问答社区
如何使用 simd 将 uint32 转换为 uint8,但不使用 avx512?
说,在对齐内存uint32 *p中有很多UINT32S商店,如何使用SIMD转换为UINT8? 我看到有_mm256_cvtepi32_epi8/vpmovdb,但它属于avx512,而我的CPU不支持它😢 解决方案 如果您真的有很多,我会做这样的事情(未经测试). 主循环读取包含16个UINT32_T值的64个字节,围绕实现截断的字节围绕的字节散装,将结果合并为单个寄存器,并使用Vector Store Orcession撰写16个字节. . void convertToBytes( const uint32_t* source, uint8_t* dest, size_t count ) { // 4 bytes of the shuffle mask to fetch bytes 0, 4, 8 and 12 from a 16-bytes source vector constexpr int shuffleScalar = 0x0C
14 2024-04-22
编程技术问答社区
如何将 uint64_t 的位对解压为 __m256i ?
考虑uint64_t,其中每个连续的2位是一个数字:b00 for 0,b01 for 1,1,b11,b11 for -1和b10未使用(永远不会发生,假设,则没有处理). 如何将这样的uint64_t解压缩到__m256i中,以便在矢量变量中签名的字节签名字节?我需要将b00>伸入b00000000,b01中b00000001和b11中b11111111,同时保留订单. 我到目前为止尝试过的是: 受启发,这个答案,我只提出了倒数过程,其中__m256i的字节被包装成位__m256i uint64_t: const __m256i vBits0 = _mm256_slli_epi16(target, 7); const int bits1 = _mm256_movemask_epi8(target); const int bits0 = _mm256_movemask_epi8(vBits0); const uint64_t withHigher = _pdep_u64(b
22 2024-04-22
编程技术问答社区
在使用 pshufb 洗牌作为 nibbles 的查找表之前,为什么需要屏蔽?
此代码来自std::uint64_t popcnt_AVX2_lookup(const uint8_t* data, const size_t n) { size_t i = 0; const __m256i lookup = _mm256_setr_epi8( /* 0 */ 0, /* 1 */ 1, /* 2 */ 1, /* 3 */ 2, /* 4 */ 1, /* 5 */ 2, /* 6 */ 2, /* 7 */ 3, /* 8 */ 1, /* 9 */ 2, /* a */ 2, /* b */ 3, /* c */ 2, /* d */ 3, /* e */ 3, /* f */ 4, /* 0 */ 0, /* 1 */ 1, /* 2 */ 1, /* 3 */ 2, /* 4 */ 1, /* 5 */ 2, /* 6 */ 2, /* 7 */ 3, /* 8 */ 1, /* 9 */ 2, /* a */ 2, /* b */ 3, /* c */ 2,
10 2024-04-22
编程技术问答社区
x86 SIMD 内核的参考手册/教程?
我正在考虑使用它们来提高某些代码的性能,但是对于*mmintrin.h标题中定义的功能似乎很难找到好的文档,任何人都可以为我提供有关这些功能的指示器吗? 编辑:特别对一个关于如何入门的非常基本的教程感兴趣. 解决方案 有一个方便的在线 Intel Intersics指南 https://www.intel.com/content/www/www/us/en/en/docs/intrinsics-guide/index.html - 它涵盖了所有Intel Simd的东西MMX通过SSE的各种口味,直至Avx2 et al . 您还可以从 intel "> intel : Intel®64和IA-32体系结构软件开发人员手册,第2A卷:指令集参考,A-M(253666-021) Intel®64和IA-32体系结构软件开发人员手册,第2B卷:指令集参考,N-Z(253667-021) intel®SSE4编程参考(D91561-001) 其他解决
14 2024-04-22
编程技术问答社区
如何交换 256 位 AVX (YMM) 寄存器的低 128 位和高 128 位?
我正在移植SSE SIMD代码以使用256位AVX扩展名,并且似乎找不到任何可以混合/shuffle/移动高128位和低128位的指令. 背景故事: 我真正想要的是VHADDPS/_mm256_hadd_ps,就像HADDPS/_mm_hadd_ps一样,只有256位单词.不幸的是,它的作用像是两个呼叫HADDPS在低音和高词上独立行动. 解决方案 使用VPERM2F128,可以交换低128和高128位(以及其他排列).乐器功能的用法看起来像 x = _mm256_permute2f128_ps( x , x , 1) 第三个参数是一个控制词,它为用户提供了很大的灵活性.请参阅 intel intel Instrinsic指南有关详细信息. 其他解决方案 x = _mm256_permute4x64_epi64(x, 0b01'00'11'10); 阅读有关它的阅读尝试在线尝试! 注意:此指令需要AVX2(不仅是AVX1). AS 评论
18 2024-04-22
编程技术问答社区
首次使用 AVX 256 位向量会降低 128 位向量和 AVX 标量运行速度
最初,我试图重现Agner Fog的Microharchituction指南中描述的效果" YMM和ZMM矢量指令的热身时期",其中说: 未使用时,处理器关闭了矢量执行单元的上部,以节省功率. 256位矢量的说明的吞吐量在大约56,000时钟周期或14μs的初始热身期间的吞吐量比正常慢4.5倍. 我的放慢速度,尽管它似乎更接近约2倍,而不是4.5倍.但是我发现的是在我的CPU上(英特尔i7-9750h咖啡湖),放缓不仅会影响256位的操作,而且还会影响128位的矢量操作和标量浮点OPS(甚至是GPR n次数) XMM接触说明后的说明). 基准程序的代码: # Compile and run: # clang++ ymm-throttle.S && ./a.out .intel_syntax noprefix .data L_F0: .asciz "ref cycles = %u\n" .p2align 5 L_C0: .long 1 .long
14 2024-04-22
编程技术问答社区
如何在 SSE/AVX 中执行 bitwise NOT?
是我的想象力,还是SSE和AVX缺少的PNOT指令?也就是说,向矢量中的每一点都翻转的指令. 如果是的,是否有比PXOR有更好的方式对其进行模拟的方法?非常烦人,因为我需要设置所有1秒的向量才能使用该方法. 解决方案 对于这样的案例,查看编译器会产生什么是有启发性的. 例如.对于以下功能: #include __m256i test(const __m256i v) { return ~v; } GCC和Clang似乎都在生成几乎相同的代码: test(long long __vector(4)): vpcmpeqd ymm1, ymm1, ymm1 vpxor ymm0, ymm0, ymm1 ret 其他解决方案 如果使用内在的,则可以使用这样的内联函数将其分开操作. inline __m256i _mm256_not_si256 (_
8 2024-04-22
编程技术问答社区
C#和SIMD:高速度和低速度。发生了什么?
引入问题 我正在尝试加快我正在编写的(2D)射线示踪剂的交点代码.我正在使用C#和System.Numerics库带来SIMD说明的速度. 问题在于,我的屋顶加速和相当低的速度会得到奇怪的结果.我的问题是,为什么一个过于屋顶,而另一个是相当低的? 上下文: Raypack struct是一系列(不同的)射线,包装在System.Numerics的向量中. 边界盒和circlepack struct是一个单个bb/circle,包装在system.numerics的向量中. 使用的CPU是I7-4710HQ(Haswell),带有SSE 4.2,AVX(2)和FMA(3)指令. 在发行模式(64位)中运行.该项目在.NET Framework 472中运行.没有其他选项设置. 尝试 我已经尝试查找某些操作是否可能得到适当支持(请注意:这些操作:这些操作适用于C ++. https://fgiesen.wordpress.com/2016/04/03
12 2024-04-17
编程技术问答社区
为什么只有AVX的处理器在许多SIMD算法中的表现优于AVX2处理器?
我一直在调查C#和C ++中SIMD算法的好处,并发现在许多情况下,在AVX处理器上使用128位寄存器的好处可提供更好的改进,而不是在AVX2上使用256位寄存器我不明白为什么. 通过改进,是指SIMD算法相对于同一机器上的非SIMD算法的加速. 解决方案 在AVX处理器上,当不执行AVX指令(VEX编码的Opcodes)时,CPU将256位寄存器和浮点单元的上半部分供电.当代码确实使用AVX指令时,CPU必须为FP单元供电 - 这大约需要70微秒,在此期间,AVX指令实际上是使用128个Micro -OPS执行的两次. 当尚未使用约700微秒的AVX指令时,CPU再次下半部. 现在之所以这样做,是因为电路的上半部分会消耗动力(doh!),因此产生热量(双doh!).这意味着当使用AVX指令时,CPU运行更热.因此,鉴于CPU在拥有热净空时可以"涡轮增压",使用AVX说明会减少此机会,实际上,CPU实际上降低了"基本时钟速度".因此,例如,如果您有一个正式计时为
10 2024-04-15
编程技术问答社区
SIMD字符串到无符号int解析在C#中的性能改进
我已经实施了一种使用.NET中可用的SIMD Intrinsics解析长度 public unsafe static uint ParseUint(string text) { fixed (char* c = text) { var parsed = Sse3.LoadDquVector128((byte*) c); var shift = (8 - text.Length) * 2; var shifted = Sse2.ShiftLeftLogical128BitLane(parsed, (byte) (shift)); Vector128 digit0 = Vector128.Create((byte) '0'); var reduced = Sse2.SubtractSaturate(shifted, digit0); var shortMult = Vector128.Create(10,
14 2024-04-12
编程技术问答社区
FLT_EPSILON用于带有SSE/AVX的第n个根的搜索器
我正在尝试转换一个函数,该函数从以下链接中找到c中的nth root的双重值 http://rosettacode.org/wiki/wiki/nth_root#c 要使用AVX一次找到8个浮子的第n个根. 该代码的一部分使用dbl_epsilon * 10.但是,当我将其转换为使用AVX的float时,我必须使用flt_epsilon * 1000或代码悬挂而不会收敛.当我打印出flt_epsilon时,我发现它是1e-7订单.但是,此链接, http://www.cplusplus.com/reference.com/reference/reference/cfloat/cfloat/ ,说应该是1E-5.当我打印出DBL_EPSILON时,它是1E-16,但链接说它应该是1E-9.发生了什么事? 这是到目前为止的代码(尚未完全优化). #include #include #include
16 2024-04-10
编程技术问答社区
为什么AVX-256 VMOVAPS指令只能复制4个单精度浮点而不是8个?
我试图熟悉一些新的英特尔处理器上可用的256位AVX说明.我已经验证了我的i7-4720HQ支持256位AVX说明.我面临的问题是,VMOVAPS指令应复制8个单个精度浮点值,仅复制4. dot PROC VMOVAPS YMM1, ymmword ptr [RCX] VDPPS YMM2, YMM1, ymmword ptr [RDX], 255 VMOVAPS ymmword ptr [RCX], YMM2 MOVSS XMM0, DWORD PTR [RCX] RET dot ENDP 如果您不熟悉通话惯例,Visual C ++ 2015希望此功能返回(因为它是float)在返回时将在XMM0中. 除此之外,标准是要在RCX中传递的第一个参数,第二个参数将在RDX中传递. 这是调用此功能的C代码.
16 2024-04-09
编程技术问答社区
如何使用AVX/SIMD的嵌套循环和+=格式?
我正在编写页面排名程序.我正在编写一种更新排名的方法.我成功地将其与nested for Loops一起工作,也可以使用螺纹版本.但是我想使用Simd/avx. 这是我想更改为SIMD/AVX实现的代码. #define IDX(a, b) ((a * npages) + b) // 2D matrix indexing for (size_t i = 0; i
16 2024-04-09
编程技术问答社区
当矩阵维数不是4的倍数时,如何避免AVX2的错误?
我使用C中的avx2,fma制作了矩阵矢量乘法程序. 但是,我遇到了"释放对象的错误校验和释放后可能会被修改." 可能会修改." 我认为,如果矩阵维度不是4的倍数. 我知道AVX2使用可以使用4个双精度浮点数的YMM寄存器.因此,如果矩阵是4的倍数,我可以使用AVX2而不会出错. 的倍数. 但是,这是我的问题. 如果矩阵不是4的倍数,我该如何有效地使用AVX2? ? 这是我的代码. #include "stdio.h" #include "math.h" #include "stdlib.h" #include "time.h" #include "x86intrin.h" void mv(double *a,double *b,double *c, int m, int n, int l) { __m256d va,vb,vc; int k; int i; for (k = 0; k
16 2024-04-09
编程技术问答社区
上证指数中的整数与浮点数的对比练习
在与SSE(AVX)中的INT和Floats打交道时,将所有INT转换为浮子并仅与浮子一起工作是一个好习惯吗? 因为之后我们只需要几个SIMD说明,我们只需要使用的是添加和比较说明(
14 2024-04-09
编程技术问答社区
使用SIMD对32位打包负数进行右移
我正在编写一些SSE/AVX代码,并且有一项任务将包装签名的32位整数除以2的补充.当值为正时,此转移效果很好,但是由于符号位而产生错误的负值结果. 是否有任何SIMD操作可以使我移动保留标志位的位置?谢谢 解决方案 sse2/av​​x2具有算术 1 与16位和32位元素尺寸的逻辑右偏移的选择. (对于64位元素,只有逻辑才能到达AVX512). 使用_mm_srai_epi32( psrad ) strong>而不是_mm_srli_epi32( psrld ). ) 请参阅英特尔的内在指南以及其他SSE标签中的链接wiki https://stackoverflow.com/tags/tags/sse/sse/info . (如果愿意,请过滤以排除AVX512,因为如今,所有3种尺寸的所有蒙版版本都非常混乱...) 或只是查看ASM指令集参考,其中包括具有它们的指令的内在信息.在中搜索"算术"您想要的移动. 注意a =算术vs. l =逻辑,而不
12 2024-04-09
编程技术问答社区
使用SIGILL与CPU探测的AVX特征检测
我正在尝试确定一种有效的方法来检测英特尔和AMD处理器上AVX和AVX2的可用性.当阅读 intel软件开发人员手册时,我很惊讶地得知它与SSE和XSAVE更接近,卷I(使用XSAVE功能SET ,第310页,管理状态). Intel发布一些用于检测AVX可用性的代码">是否启用了AVX?代码如下所示,它的代码不太痛苦.问题是,Visual Studio是一个痛苦点,因为我们需要将代码从C/C ++文件中移出X64的ASM文件. 其他人似乎正在采用SIGILL检测AVX可用性的方法.或者他们不知不觉地使用SIGILL方法.参见,例如,我的问题是,使用SIGILL检测AVX可用性是否安全?在这里," SAFE" 是指AVX指令将不是生成SIGILL当CPU和OS支持AVX时;它将生成SIGILL否则. 下面的代码适用于32位计算机及其来自英特尔博客启用了AVX?担心我的东西是在操纵控制寄存器.读写一些X86和ARM控制寄存器有时需要超级用户/管理员特权.这是我更喜欢a S
6 2024-04-09
编程技术问答社区