Tag: avx

FLT_EPSILON用于具有SSE / AVX的第n个根查找器

我正在尝试转换一个函数,在C中找到第n个根,从以下链接http://rosettacode.org/wiki/Nth_root#C获取一个double值,使用AVX一次找到8个浮点数的第n个根。 部分代码使用DBL_EPSILON * 10.但是,当我将其转换为使用浮点数和AVX时,我必须使用FLT_EPSILON * 1000或代码挂起并且不会收敛。 当我打印出FLT_EPSILON时,我看到它是订单1E-7。 但是这个链接http://www.cplusplus.com/reference/cfloat/表示它应该是1E-5。 当我打印出DBL_EPSILON时它是1E-16但链接说它应该只是1E-9。 这是怎么回事? 这是迄今为止的代码(未完全优化)。 #include #include #include // AVX inline double abs_(double x) { return x >= 0 ? x : -x; } double pow_(double x, int e) { double ret = 1; for (ret = 1; e; x *= x, e >>= 1) { if ((e & […]

当矩阵维数不是4的倍数时,如何避免AVX2的错误?

我使用AVX2,C中的FMA制作了矩阵向量乘法程序。我使用GCC ver7编译了-mfma,-mavx。 但是,我收到错误“释放对象的校验和不正确 – 对象可能在被释放后被修改。” 我认为如果矩阵维度不是4的倍数,则会产生错误。 我知道AVX2使用ymm寄存器,可以使用4个双精度浮点数。 因此,如果矩阵是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 < l; k++) { vb = _mm256_broadcast_sd(&b[k]); for (i = […]

为什么AVX-256 VMOVAPS指令只复制四个单精度浮点而不是8?

我试图熟悉一些较新的英特尔处理器上提供的256位AVX指令。 我已经validation我的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期望在返回时返回此函数(因为它是一个浮点数)在XMM0中。 除此之外,标准是第一个参数在RCX中传递,第二个参数在RDX中传递。 这是调用此函数的C代码。 _declspec(align(32)) float d1[] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; _declspec(align(32)) float d2[] = { […]

SSE对冲浮标练习

在处理SSE(AVX)中的整数和浮点数时,将所有整数转换为浮点数并仅使用浮点数是一个好习惯吗? 因为之后我们只需要一些SIMD指令,而我们需要使用的是添加和比较指令( <, <=, == ),我希望这种转换应该完全保留。

使用SIGILL与CPU探测进行AVXfunction检测

我正在尝试确定一种检测英特尔和AMD处理器上AVX和AVX2可用性的有效方法。 在阅读英特尔软件开发人员手册第一卷( 使用XSAVEfunction集管理状态 ,第310页)时,我更加惊讶地发现它更接近SSE和XSAVE。 英特尔发布了一些用于在启用Is AVX时检测AVX可用性的代码? 代码如下所示,并不太痛苦。 问题是,Visual Studio是一个痛点,因为我们需要将代码从C / C ++文件中移出到X64的ASM文件中。 其他人似乎采用SIGILL方法来检测AVX可用性。 或者他们无意中使用了SIGILL方法。 例如,请参阅AVX指令上的SIGILL 。 我的问题是,使用SIGILL方法检测AVX可用性是否安全? 这里, “安全”表示当CPU和OS支持AVX时,AVX指令不会生成SIGILL ; 否则它会生成一个SIGILL 。 下面的代码适用于32位计算机,它来自英特尔博客是否已启用AVX? 令我担心的是操纵控制寄存器。 读取和写入某些X86和ARM控制寄存器有时需要超级用户/管理员权限。 这是我更喜欢SIGILL (并避免控制寄存器)的原因。 ; int isAvxSupported(); isAvxSupported proc xor eax, eax cpuid cmp eax, 1 ; does CPUID support eax = 1? jb not_supported mov eax, 1 cpuid and ecx, 018000000h […]

提示编译器可以使用对齐的memcpy

我有一个由7个__m256值组成的结构,它在内存中以32字节对齐的方式存储。 typedef struct { __m256 xl,xh; __m256 yl,yh; __m256 zl,zh; __m256i co; } bloxset8_t; 我通过对动态分配的数据使用posix_memalign()函数或对静态分配的数据使用(aligned(32))属性来实现32字节对齐。 对齐很好,但是当我使用两个指向这样的结构的指针,并将它们作为memcpy()的目标和源传递时,编译器决定使用__memcpy_avx_unaligned()进行复制。 我怎样才能强制clang使用对齐的avx memcpy函数,我认为它是更快的变体? 操作系统:Ubuntu 16.04.3 LTS,Clang:3.8.0-2ubuntu4。 UPDATE 仅在复制两个或多个结构时才会调用__memcpy_avx_unaligned()。 当只复制一个时,clang会发出14个vmovup指令。

C风格演员与内在演员

假设我已经定义了__m256d x并且我想要提取较低的128位。 我会做: __m128d xlow = _mm256_castpd256_pd128(x); 但是,我最近看到有人这样做: __m128d xlow = (__m128d) x 是否有首选方法用于演员表? 为什么要使用第一种方法?

为什么_mm256_load_pd编译为MOVUPD而不是MOVAPD?

为什么以下代码会产生未对齐的AVX指令(MOVUPD而不是MOVAPD)? 我在Visual Studio 2015上编译了这个。如何告诉编译器我的数据确实是对齐的? const size_t ALIGN_SIZE = 64; const size_t ARRAY_SIZE = 1024; double __declspec(align(ALIGN_SIZE)) a[ARRAY_SIZE]; double __declspec(align(ALIGN_SIZE)) b[ARRAY_SIZE]; //Calculate the dotproduct __m256d ymm0 = _mm256_set1_pd(0.0); for (int i = 0; i < ARRAY_SIZE; i += 8) { __m256d ymm1 = _mm256_load_pd(a + i); __m256d ymm2 = _mm256_load_pd(b + i); __m256d ymm3 = _mm256_mul_pd(ymm1, […]

Websocket数据取消屏蔽/多字节xor

websocket规范将unmasking数据定义为 j = i MOD 4 transformed-octet-i = original-octet-i XOR masking-key-octet-j 其中mask是4个字节长,每个字节必须应用unmasking。 有没有办法更有效地做到这一点,而不仅仅是循环字节? 运行代码的服务器可以假定为Haswell CPU,OS是内核> 3.2的Linux,因此SSE等都存在。 编码是在C语言中完成的,但如果需要,我也可以执行asm。 我试图自己查找解决方案,但是无法弄清楚是否有任何SSE1-5 / AVE /中的任何一个都有适当的指令(无论多少扩展 – 多年来失去了很多轨道) 非常感谢你! 编辑:重新阅读规范几次之后,似乎它实际上只是用掩码字节对数据字节进行异或,我可以一次做8个字节,直到最后几个字节。 问题仍然存在,因为我认为可能仍然有一种方法可以使用SSE等来优化它(可能一次只处理16个字节?让进程执行for循环?…)

如何使用avx指令将float向量转换为short int?

基本上我怎么能用AVX2内在函数写出相当于这个? 我们假设result_in_float的类型为__m256 ,而result的类型为short int*或short int[8] 。 for(i = 0; i < 8; i++) result[i] = (short int)result_in_float[i]; 我知道使用__m256i _mm256_cvtps_epi32(__m256 m1)内在函数可以将浮点数转换为32位整数,但不知道如何将这些32位整数进一步转换为16位整数。 我不仅仅想要这样,而且还要将这些值(以16位整数的forms)存储到存储器中,我想使用向量指令来完成所有这些操作。 在互联网上搜索,我找到了一个名为_mm256_mask_storeu_epi16的内在函数,但是我不确定是否会这样做,因为我找不到它的用法示例。