avx

RyuJIT not making full use of SIMD intrinsics

 ̄綄美尐妖づ 提交于 2019-12-05 11:46:07
问题 I'm running some C# code that uses System.Numerics.Vector<T> but as far as I can tell I'm not getting the full benefit of SIMD intrinsics. I'm using Visual Studio Community 2015 with Update 1, and my clrjit.dll is v4.6.1063.1. I'm running on an Intel Core i5-3337U Processor, which implements the AVX instruction set extensions. Therefore, I figure, I should be able to execute most SIMD instructions on a 256 bit register. For example, the disassembly should contain instructions like vmovups ,

Does ICC satisfy C99 specs for multiplication of complex numbers?

倖福魔咒の 提交于 2019-12-05 10:58:32
问题 Consider this simple code: #include <complex.h> complex float f(complex float x) { return x*x; } If you compile it with -O3 -march=core-avx2 -fp-model strict using the Intel Compiler you get: f: vmovsldup xmm1, xmm0 #3.12 vmovshdup xmm2, xmm0 #3.12 vshufps xmm3, xmm0, xmm0, 177 #3.12 vmulps xmm4, xmm1, xmm0 #3.12 vmulps xmm5, xmm2, xmm3 #3.12 vaddsubps xmm0, xmm4, xmm5 #3.12 ret This is much simpler code than you get from both gcc and clang and also much simpler than the code you will find

Simd matmul program gives different numerical results

会有一股神秘感。 提交于 2019-12-05 10:28:46
I am trying to program the matrix multiplication in C using simd intrinsics. I was pretty sure of my implementation, but when I execute, i get some numerical errors starting from the 5th digit of the resulting matrix's coefficients. REAL_T is just a float with typedef /* This is my matmul Version with simd, using floating simple precision*/ void matmul(int n, REAL_T *A, REAL_T *B, REAL_T *C){ int i,j,k; __m256 vA, vB, vC, vRes; for (i=0; i<n; i++){ for (j=0; j<n; j++){ for (k=0; k<n; k= k+8){ vA = _mm256_load_ps(&A[i*n+k]); vB = _mm256_loadu_ps(&B[k*n+j]); vC = _mm256_mul_ps(vA, vB); vC =

Storing individual doubles from a packed double vector using Intel AVX

别说谁变了你拦得住时间么 提交于 2019-12-05 10:04:34
I'm writing code using the C intrinsics for Intel's AVX instructions. If I have a packed double vector (a __m256d ), what would be the most efficient way (i.e. the least number of operations) to store each of them to a different place in memory (i.e. I need to fan them out to different locations such that they are no longer packed)? Pseudocode: __m256d *src; double *dst; int dst_dist; dst[0] = src[0]; dst[dst_dist] = src[1]; dst[2 * dst_dist] = src[2]; dst[3 * dst_dist] = src[3]; Using SSE, I could do this with __m128 types using the _mm_storel_pi and _mm_storeh_pi intrinsics. I've not been

Is there, or will there be, a “global” version of the target_clones attribute?

依然范特西╮ 提交于 2019-12-05 08:04:25
I've recently played around with the target_clones attribute available from gcc 6.1 and onward. It's quite nifty, but, for now, it requires a somewhat clumsy approach; every function that one wants multi-versioned has to have an attribute declared manually. This is less than optimal because: It puts compiler-specific stuff in the code. It requires the developer to identify which functions should receive this treatment. Let's take the example where I want to compile some code that will take advantage of AVX2 instructions, where available. -fopt-info-vect will tell me which functions were

Efficient way of rotating a byte inside an AVX register

回眸只為那壹抹淺笑 提交于 2019-12-05 06:44:39
Summary/tl;dr: Is there any way to rotate a byte in an YMM register bitwise (using AVX), other than doing 2x shifts and blending the results together? For each 8 bytes in an YMM register, I need to left-rotate 7 bytes in it. Each byte needs to be rotated one bit more to the left than the former. Thus the 1 byte should be rotated 0 bits and the seventh should be rotated 6 bits. Currently, I have made an implementation that does this by [I use the 1-bit rotate as an example here] shifting the register 1 bit to the left, and 7 to the right individually. I then use the blend operation (intrinsic

Matrix-vector-multiplication in AVX not proportionately faster than in SSE

一世执手 提交于 2019-12-05 04:46:04
I was writing a matrix-vector-multiplication in both SSE and AVX using the following: for(size_t i=0;i<M;i++) { size_t index = i*N; __m128 a, x, r1; __m128 sum = _mm_setzero_ps(); for(size_t j=0;j<N;j+=4,index+=4) { a = _mm_load_ps(&A[index]); x = _mm_load_ps(&X[j]); r1 = _mm_mul_ps(a,x); sum = _mm_add_ps(r1,sum); } sum = _mm_hadd_ps(sum,sum); sum = _mm_hadd_ps(sum,sum); _mm_store_ss(&C[i],sum); } I used a similar method for AVX, however at the end, since AVX doesn't have an equivalent instruction to _mm_store_ss() , I used: _mm_store_ss(&C[i],_mm256_castps256_ps128(sum)); The SSE code gives

Choice between aligned vs. unaligned x86 SIMD instructions

橙三吉。 提交于 2019-12-05 03:21:53
There are generally two types of SIMD instructions: A. Ones that work with aligned memory addresses, that will raise general-protection (#GP) exception if the address is not aligned on the operand size boundary: movaps xmm0, xmmword ptr [rax] vmovaps ymm0, ymmword ptr [rax] vmovaps zmm0, zmmword ptr [rax] B. And the ones that work with unaligned memory addresses, that will not raise such exception: movups xmm0, xmmword ptr [rax] vmovups ymm0, ymmword ptr [rax] vmovups zmm0, zmmword ptr [rax] But I'm just curious, why would I want to shoot myself in the foot and use aligned memory instructions

performance of SSE and AVX when both Memory-band width limited

痴心易碎 提交于 2019-12-05 02:44:54
问题 In the code below I changed the "dataLen" and get different efficiency. dataLen = 400 SSE time:758000 us AVX time:483000 us SSE > AVX dataLen = 2400 SSE time:4212000 us AVX time:2636000 us SSE > AVX dataLen = 2864 SSE time:6115000 us AVX time:6146000 us SSE ~= AVX dataLen = 3200 SSE time:8049000 us AVX time:9297000 us SSE < AVX dataLen = 4000 SSE time:10170000us AVX time:11690000us SSE < AVX The SSE and AVX code can be both simplified into this: buf3[i] += buf1[1]*buf2[i]; #include "testfun.h

Optimal uint8_t bitmap into a 8 x 32bit SIMD “bool” vector

坚强是说给别人听的谎言 提交于 2019-12-05 02:36:45
问题 As part of a compression algorithm, I am looking for the optimal way to achieve the following: I have a simple bitmap in a uint8_t . For example 01010011 What I want is a __m256i of the form: (0, maxint, 0, maxint, 0, 0, maxint, maxint) One way to achieve this is by shuffling a vector of 8 x maxint into a vector of zeros. But that first requires me to expand my uint8_t to the right shuffle bitmap. I am wondering if there is a better way? 回答1: Here is a solution (PaulR improved my solution,