sse

How do initialize an SIMD vector with a range from 0 to N?

安稳与你 提交于 2019-12-03 20:50:21
I have the following function I'm trying to write an AXV version for: 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) % i; temp = str[i]; str[i] = str[j]; str[j] = temp; } } I'm trying to vectorize v %= salt_length; . I want to initialize a vector that contains numbers from 0 to str_length in order to use SVML's _mm_rem_epu64 in order to calculate v for each loop iteration. How do I

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

谁都会走 提交于 2019-12-03 20:43:56
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" #include <iostream> #include <chrono> #include <malloc.h> #include "immintrin.h" using namespace std:

__m256d TRANSPOSE4 Equivalent?

心已入冬 提交于 2019-12-03 20:14:55
Intel has included __MM_TRANPOSE4_PS to transpose a 4x4 matrix of vectors. I'm wanting to do the equivalent with __m256d. However, I can't seem to figure out how to get _mm256_shuffle_pd in the same manner. _MM_TRANSPOSE4_PS Code #define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) { \ __m128 tmp3, tmp2, tmp1, tmp0; \ \ tmp0 = _mm_shuffle_ps((row0), (row1), 0x44); \ tmp2 = _mm_shuffle_ps((row0), (row1), 0xEE); \ tmp1 = _mm_shuffle_ps((row2), (row3), 0x44); \ tmp3 = _mm_shuffle_ps((row2), (row3), 0xEE); \ \ (row0) = _mm_shuffle_ps(tmp0, tmp1, 0x88); \ (row1) = _mm_shuffle_ps(tmp0, tmp1, 0xDD); \

Complex Mul and Div using sse Instructions

时光毁灭记忆、已成空白 提交于 2019-12-03 17:47:53
问题 Is performing complex multiplication and division beneficial through SSE instructions? I know that addition and subtraction perform better when using SSE. Can someone tell me how I can use SSE to perform complex multiplication to get better performance? 回答1: Just for completeness, the Intel® 64 and IA-32 Architectures Optimization Reference Manual that can be downloaded here contains assembly for complex multiply (Example 6-9) and complex divide (Example 6-10). Here's for example the multiply

Faster quaternion vector multiplication doesn't work

岁酱吖の 提交于 2019-12-03 17:17:17
I need a faster quaternion-vector multiplication routine for my math library. Right now I'm using the canonical v' = qv(q^-1) , which produces the same result as multiplying the vector by a matrix made from the quaternion, so I'm confident in it's correctness. So far I've implemented 3 alternative "faster" methods: #1, I have no idea where I got this one from: v' = (q.xyz * 2 * dot(q.xyz, v)) + (v * (q.w*q.w - dot(q.xyz, q.zyx))) + (cross(q.xyz, v) * q.w * w) Implemented as: vec3 rotateVector(const quat& q, const vec3& v) { vec3 u(q.x, q.y, q.z); float s = q.w; return vec3(u * 2.0f * vec3::dot

When program will benefit from prefetch & non-temporal load/store?

夙愿已清 提交于 2019-12-03 17:09:28
问题 I did a test with this for (i32 i = 0; i < 0x800000; ++i) { // Hopefully this can disable hardware prefetch i32 k = (i * 997 & 0x7FFFFF) * 0x40; _mm_prefetch(data + ((i + 1) * 997 & 0x7FFFFF) * 0x40, _MM_HINT_NTA); for (i32 j = 0; j < 0x40; j += 0x10) { //__m128 v = _mm_castsi128_ps(_mm_stream_load_si128((__m128i *)(data + k + j))); __m128 v = _mm_load_ps((float *)(data + k + j)); a_single_chain_computation //_mm_stream_ps((float *)(data2 + k + j), v); _mm_store_ps((float *)(data2 + k + j), v

difference between MMX and XMM register?

[亡魂溺海] 提交于 2019-12-03 16:51:52
问题 I'm currently learning assembly programming on Intel x86 processor. Could someone please explain to me, what is the difference between MMX and XMM register? I'm very confused in terms of what functions they serve and the difference and similarities between them? 回答1: MM registers are the registers used by the MMX instruction set, one of the first attempts to add (integer-only) SIMD to x86. They are 64 bit wide and they are actually aliases for the mantissa parts of the x87 registers (but they

Push XMM register to the stack

馋奶兔 提交于 2019-12-03 16:29:30
问题 Is there a way of pushing a packed doubleword integer from XMM register to the stack? and then later on pop it back when needed? Ideally I am looking for something like PUSH or POP for general purpose registers, I have checked Intel manuals but I either missed the command or there isn't one... Or will I have to unpack values to general registers and then push them? 回答1: No, there is no such a asm instruction under x86, but you can do something like: //Push xmm0 sub esp, 16 movdqu dqword [esp]

Why is prefetch speedup not greater in this example?

耗尽温柔 提交于 2019-12-03 16:07:00
In 6.3.2 of this this excellent paper Ulrich Drepper writes about software prefetching. He says this is the "familiar pointer chasing framework" which I gather is the test he gives earlier about traversing randomized pointers. It makes sense in his graph that performance tails off when the working set exceeds the cache size, because then we are going to main memory more and more often. But why does prefetch help only 8% here? If we are telling the processor exactly what we want to load, and we tell it far enough ahead of time (he does it 160 cycles ahead), why isn't every access satisfied by

SSE Instructions: Byte+Short

喜你入骨 提交于 2019-12-03 15:32:43
I have very long byte arrays that need to be added to a destination array of type short (or int ). Does such SSE instruction exist? Or maybe their set ? You need to unpack each vector of 8 bit values to two vectors of 16 bit values and then add those. __m128i v = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); __m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0)); // vl = { 7, 6, 5, 4, 3, 2, 1, 0 } __m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0)); // vh = { 15, 14, 13, 12, 11, 10, 9, 8 } where v is a vector of 16 x 8 bit values and vl , vh are the two unpacked vectors of 8