Tag: intrinsics

如何初始化范围从0到N的SIMD向量?

我有以下函数我正在尝试编写一个AXV版本: void hashids_shuffle(char *str, size_t str_length, char *salt, size_t salt_length) { size_t i, j, v, p; char temp; if (!salt_length) { return; } for (i = str_length – 1, v = 0, p = 0; i > 0; –i, ++v) { v %= salt_length; p += salt[v]; j = (salt[v] + v + p) % […]

使用NEON内在函数除以浮点数

我当时正在处理一个四像素的图像,这在Android应用程序的armv7 。 我想将float32x4_t向量除以另一个向量,但其中的数字从大约0.7到3.85不等,在我看来,除法的唯一方法是使用右移,但这是一个2^n 。 此外,我是新手,所以欢迎任何建设性的帮助或评论。 例: 如何使用NEON内在函数执行这些操作? float32x4_t a = {25.3,34.1,11.0,25.1}; float32x4_t b = {1.2,3.5,2.5,2.0}; // somthing like this float32x4 resultado = a/b; // {21.08,9.74,4.4,12.55}

如何在ARM Cortex-a8中使用乘法和累加内在函数?

如何使用GCC提供的Multiply-Accumulate内在函数? float32x4_t vmlaq_f32 (float32x4_t , float32x4_t , float32x4_t); 任何人都可以解释我必须传递给这个函数的三个参数。 我的意思是源和目标寄存器以及函数返回的内容? 救命!!!

将__m256i存储为整数

如何将__m256i数据类型存储为整数? 我知道浮子有: _mm256_store_ps(float *a, __m256 b) 其中第一个参数是输出数组。 对于整数我只发现: _mm256_store_si256(__m256i *a, __m256i b) 其中两个参数都是__m256i数据类型。 做这样的事情就足够了: int * X = (int*) _mm_malloc( N * sizeof (*X) ,32 ); (我使用它作为函数的参数,我想获得它的值) 内部function: __m256i * Xmmtype = (__m256i*) X; //fill output _mm256_store_si256( &Xmmtype[ i ] , T ); //T is __m256i 这个可以吗? – – -更新 – – – – – […]

adcx和adox的测试用例

我正在测试带有进位的英特尔ADX添加和添加溢出到管道添加大整数。 我想看看预期的代码生成应该是什么样子。 从_addcarry_u64和_addcarryx_u64与MSVC和ICC ,我认为这将是一个合适的测试用例: #include #include #include “immintrin.h” int main(int argc, char* argv[]) { #define MAX_ARRAY 100 uint8_t c1 = 0, c2 = 0; uint64_t a[MAX_ARRAY]={0}, b[MAX_ARRAY]={0}, res[MAX_ARRAY]; for(unsigned int i=0; i< MAX_ARRAY; i++){ c1 = _addcarryx_u64(c1, res[i], a[i], (unsigned long long int*)&res[i]); c2 = _addcarryx_u64(c2, res[i], b[i], (unsigned long long int*)&res[i]); } return 0; […]

__m256类型的intel内在函数问题

我正在尝试测试一些英特尔内部函数,看看它们是如何工作的。 所以,我创建了一个函数来为我做这个,这是代码: void test_intel_256() { __m256 res,vec1,vec2; __M256_MM_SET_PS(vec1, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0); __M256_MM_SET_PS(vec1, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0); __M256_MM_ADD_PS(res,vec1,vec2); if (res[0] ==9 && res[1] ==9 && res[2] ==9 && res[3] ==9 && res[4] ==9 && res[5] ==9 && res[6] ==9 && res[7] ==9 ) printf(“Addition : OK!\n”); else […]

在GCC中使用不同版本的SSE内在函数的正确方法是什么?

我举一个例子来问我的问题。 现在我有一个名为do_something()的函数。 它有三个版本: do_something() , do_something_sse3()和do_something_sse4() 。 当我的程序运行时,它将检测CPUfunction(看它是否支持SSE3或SSE4)并相应地调用三个版本之一。 问题是:当我使用GCC构建程序时,我必须为do_something_sse4()设置-msse4以进行编译(例如,要包含头文件 )。 但是,如果我设置-msse4 ,则允许gcc使用SSE4指令, do_something_sse3()一些内在函数也会转换为某些SSE4指令。 因此,如果我的程序在仅支持SSE3(但没有SSE4)的CPU上运行,则在调用do_something_sse3()时会导致“非法指令”。 也许我有一些不好的做法。 你能提一些建议吗? 谢谢。

NEON pack vector将结果比较到位图

我有两个浮点操作数的比较结果如下; 我需要做的是基于比较的结果需要执行以下操作:即: neon_gt_res = vcgtq_f32(temp1, temp2); if(neon_gt_res[0]) array[0] |= (unsigned char)0x01; if(neon_gt_res[1]) array[0] |= (unsigned char)0x02; if(neon_gt_res[2]) array[0] |= (unsigned char)0x04; if(neon_gt_res[3]) array[0] |= (unsigned char)0x08; 但是这样的写作再次等同于多重比较。 我如何在氖C内在函数中以最佳方式编写它。 在x86上,这将是array[0] |= _mm_movemask_ps(cmp_gt_res);

在_mm256_rsqrt_ps()中处理零

鉴于_mm256_sqrt_ps()相对较慢,并且我生成的值会立即被_mm256_floor_ps()截断,看看它似乎在做: _mm256_mul_ps(_mm256_rsqrt_ps(eightFloats), eightFloats); 是获得额外性能和避免管道停滞的方法。 不幸的是,零值,我当然得到崩溃计算1/sqrt(0) 。 围绕这个的最佳方法是什么? 我试过这个(有效并且更快),但是有更好的方法,还是我会在某些条件下遇到问题? _mm256_mul_ps(_mm256_rsqrt_ps(_mm256_max_ps(eightFloats, _mm256_set1_ps(0.1))), eightFloats); 我的代码用于垂直应用程序,因此我可以假设它将在Haswell CPU(i7-4810MQ)上运行,因此可以使用FMA / AVX2。 原始代码大约是: float vals[MAX]; int sum = 0; for (int i = 0; i < MAX; i++) { int thisSqrt = (int) floor(sqrt(vals[i])); sum += min(thisSqrt, 0x3F); } vals所有值都应该是整数值。 (为什么一切都不仅仅是int是一个不同的问题…)

缺少面具的AVX-512内在函数?

英特尔的内在指南列出了 AVX-512 K *掩码指令的一些内在函数 ,但似乎有一些缺失: KSHIFT {L / R} KADD KTEST 英特尔开发人员手册声称内在函数不是必需的,因为它们是由编译器自动生成的。 一个人怎么做呢? 如果这意味着__mmask *类型可以被视为常规整数,那么它会很有意义,但是像mask << 4这样的测试似乎会导致编译器将掩码移动到常规寄存器,移动它,然后再移回到面具。 这是使用Godbolt最新的GCC和ICC -O2 -mavx512bw 。 另外有趣的是,内在函数只处理__mmask16而不是其他类型。 我没有测试太多,但看起来ICC并不介意采用不正确的类型,但GCC似乎确实尝试确保掩码中只有16位,如果你使用内在函数。 我是不是在寻找上述指令的正确内在函数,以及其他__mmask *类型变体,还是有其他方法可以实现相同的东西而不需要求助于内联汇编?