intrinsics

Why does this simple C++ SIMD benchmark run slower when SIMD instructions are used?

陌路散爱 提交于 2019-12-24 21:37:44
问题 I'm thinking about writing a SIMD vector math library, so as a quick benchmark I wrote a program that does 100 million (4 float) vector element-wise multiplications and adds them to a cumulative total. For my classic, non-SIMD variation I just made a struct with 4 floats and wrote my own multiply function "multiplyTwo" that multiplies two such structs element wise and returns another struct. For my SIMD variation I used "immintrin.h" along with __m128, _mm_set_ps, and _mm_mul_ps. I'm running

error: '_mm512_loadu_epi64' was not declared in this scope

可紊 提交于 2019-12-24 19:29:34
问题 I'm trying to create a minimal reproducer for this issue report. There seems to be some problems with AVX-512, which is shipping on the latest Apple machines with Skylake processors. According to GCC6 release notes the AVX-512 gear should be available. According to the Intel Intrinsics Guide vmovdqu64 is available with AVX-512VL and AVX-512F : $ cat test.cxx #include <cstdint> #include <immintrin.h> int main(int argc, char* argv[]) { uint64_t x[8]; __m512i y = _mm512_loadu_epi64(x); return 0;

Deinterleave and convert float to uint16_t efficiently

北城余情 提交于 2019-12-24 11:36:43
问题 I need to deinterleave a packed image buffer (YUVA) of floats to planar buffers. I would also like to convert these float s to uint16_t , but this is really slow. My question is: How do I speed this up by using intrinsics? void deinterleave(char* pixels, int rowBytes, char *bufferY, char *bufferU, char *bufferV, char *bufferA) { // Scaling factors (note min. values are actually negative) (limited range) const float yuva_factors[4][2] = { { 0.07306f, 1.09132f }, // Y { 0.57143f, 0.57143f }, //

How to detect rdtscp support in Visual C++?

走远了吗. 提交于 2019-12-24 10:49:38
问题 I have a piece of code running on MSVC 2012: #include <windows.h> #include <intrin.h> UINT64 gettime() { try { unsigned int ui; return __rdtscp(&ui); } catch (...) { return __rdtsc(); } } I was trying to use __rdtscp() to get the timestamp; however, on the platform where the __rdtscp() is not supported, I want to switch to __rdtsc() instead. The above code doesn't work; the program simply crashed if the __rdtscp() is not supported (on certain VMs). So is there any way I can detect if the _

-O2 in ICC messes up assembler, fine with -O1 in ICC and all optimizations in GCC / Clang

别等时光非礼了梦想. 提交于 2019-12-24 10:35:34
问题 I was recently starting to use ICC (18.0.1.126) to compile a code that worked fine with GCC and Clang on arbitrary optimization settings. The code contains an assembler routine that multiplies 4x4 matrices of doubles using AVX2 and FMA instructions. After much fiddling it turned out that the assembler routine is working properly when compiled with -O1 - xcore-avx2, but gives a wrong numerical result when compiled with -O2 - xcore-avx2. The code compiles however without any error messages on

Find 4 minimal values in 4 __m256d registers

北城以北 提交于 2019-12-23 22:29:02
问题 I cannot figure out how to implement: __m256d min(__m256d A, __m256d B, __m256d C, __m256d D) { __m256d result; // result should contain 4 minimal values out of 16 : A[0], A[1], A[2], A[3], B[0], ... , D[3] // moreover it should be result[0] <= result[1] <= result[2] <= result[2] return result; } Any ideas of how to use _mm256_min_pd , _mm256_max_pd and shuffles/permutes in a smart way? ================================================== This where I got so far, after: __m256d T = _mm256_min

FMA instruction showing up as three packed double operations?

China☆狼群 提交于 2019-12-23 19:03:34
问题 I'm analyzing a piece of linear algebra code which is calling intrinsics directly, e.g. v_dot0 = _mm256_fmadd_pd( v_x0, v_y0, v_dot0 ); My test script computes the dot product of two double precision vectors of length 4 (so only one call to _mm256_fmadd_pd needed), repeated 1 billion times. When I count the number of operations with perf I get something as follows: Performance counter stats for './main': 0 r5380c7 (skl::FP_ARITH:512B_PACKED_SINGLE) (49.99%) 0 r5340c7 (skl::FP_ARITH:512B

Benefits of using clang builtins vs standard functions

倾然丶 夕夏残阳落幕 提交于 2019-12-23 18:42:25
问题 Clang and GCC define a bunch of builtin functions I'll use the example of remainder here: __builtin_sqrt(x) However, standard C99 defines the following in math.h sqrt(x) What's the point of clang defining a builtin for a method that already exists? I'd have thought common math functions such as sqrt would be optimised by the backend so doesn't really need a builtin. This builtins are less portable than standard c, for obvious reasons. 回答1: From gcc manual: GCC normally generates special code

SSE Loading & Adding

最后都变了- 提交于 2019-12-23 12:52:31
问题 Assume I have two vectors represented by two arrays of type double , each of size 2. I'd like to add corresponding positions. So assume vectors i0 and i1 , I'd like to add i0[0] + i1[0] and i0[1] + i1[1] together. Since the type is double , I would need two registers. The trick would be to put i0[0] and i1[0] , and i0[1] and i1[1] in another and just add the register with itself. My question is, if I call _mm_load_ps(i0[0]) and then _mm_load_ps(i1[0]) , will that place them in the lower and

Best way to shuffle 64-bit portions of two __m128i's

我们两清 提交于 2019-12-23 07:49:54
问题 I have two __m128i s, a and b , that I want to shuffle so that the upper 64 bits of a fall in the lower 64 bits of dst and the lower 64 bits of b fall in the upper 64 of dst . i.e. dst[ 0:63] = a[64:127] dst[64:127] = b[0:63] Equivalent to: __m128i dst = _mm_unpacklo_epi64(_mm_srli_si128i(a, 8), b); or __m128i dst = _mm_castpd_si128(mm_shuffle_pd(_mm_castsi128_pd(a),_mm_castsi128_pd(b),1)); Is there a better way to do this than the first method? The second one is just one instruction, but the