mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Add AVX and unaligned protokernels
This commit is contained in:
		| @@ -59,6 +59,140 @@ | |||||||
| #include <inttypes.h> | #include <inttypes.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_AVX | ||||||
|  | #include <immintrin.h> | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_32f_index_max_32u_a_avx(uint32_t* target, const float* src0, uint32_t num_points) | ||||||
|  | { | ||||||
|  |     if(num_points > 0) | ||||||
|  |         { | ||||||
|  |             uint32_t number = 0; | ||||||
|  |             const uint32_t quarterPoints = num_points / 8; | ||||||
|  |  | ||||||
|  |             float* inputPtr = (float*)src0; | ||||||
|  |  | ||||||
|  |             __m256 indexIncrementValues = _mm256_set1_ps(8); | ||||||
|  |             __m256 currentIndexes = _mm256_set_ps(-1,-2,-3,-4,-5,-6,-7,-8); | ||||||
|  |  | ||||||
|  |             float max = src0[0]; | ||||||
|  |             float index = 0; | ||||||
|  |             __m256 maxValues = _mm256_set1_ps(max); | ||||||
|  |             __m256 maxValuesIndex = _mm256_setzero_ps(); | ||||||
|  |             __m256 compareResults; | ||||||
|  |             __m256 currentValues; | ||||||
|  |  | ||||||
|  |             __VOLK_ATTR_ALIGNED(32) float maxValuesBuffer[8]; | ||||||
|  |             __VOLK_ATTR_ALIGNED(32) float maxIndexesBuffer[8]; | ||||||
|  |  | ||||||
|  |             for(;number < quarterPoints; number++) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                     currentValues  = _mm256_load_ps(inputPtr); inputPtr += 8; | ||||||
|  |                     currentIndexes = _mm256_add_ps(currentIndexes, indexIncrementValues); | ||||||
|  |  | ||||||
|  |                     //compareResults = _mm_cmpgt_ps(maxValues, currentValues); | ||||||
|  |                     compareResults = _mm256_cmp_ps(maxValues, currentValues, 0x1e); | ||||||
|  |  | ||||||
|  |                     maxValuesIndex = _mm256_blendv_ps(currentIndexes, maxValuesIndex, compareResults); | ||||||
|  |                     maxValues      = _mm256_blendv_ps(currentValues, maxValues, compareResults); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             // Calculate the largest value from the remaining 8 points | ||||||
|  |             _mm256_store_ps(maxValuesBuffer, maxValues); | ||||||
|  |             _mm256_store_ps(maxIndexesBuffer, maxValuesIndex); | ||||||
|  |  | ||||||
|  |             for(number = 0; number < 8; number++) | ||||||
|  |                 { | ||||||
|  |                     if(maxValuesBuffer[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = maxIndexesBuffer[number]; | ||||||
|  |                             max = maxValuesBuffer[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             number = quarterPoints * 8; | ||||||
|  |             for(;number < num_points; number++) | ||||||
|  |                 { | ||||||
|  |                     if(src0[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = number; | ||||||
|  |                             max = src0[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |             target[0] = (uint32_t)index; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /*LV_HAVE_AVX*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_AVX | ||||||
|  | #include <immintrin.h> | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_32f_index_max_32u_u_avx(uint32_t* target, const float* src0, uint32_t num_points) | ||||||
|  | { | ||||||
|  |     if(num_points > 0) | ||||||
|  |         { | ||||||
|  |             uint32_t number = 0; | ||||||
|  |             const uint32_t quarterPoints = num_points / 8; | ||||||
|  |  | ||||||
|  |             float* inputPtr = (float*)src0; | ||||||
|  |  | ||||||
|  |             __m256 indexIncrementValues = _mm256_set1_ps(8); | ||||||
|  |             __m256 currentIndexes = _mm256_set_ps(-1,-2,-3,-4,-5,-6,-7,-8); | ||||||
|  |  | ||||||
|  |             float max = src0[0]; | ||||||
|  |             float index = 0; | ||||||
|  |             __m256 maxValues = _mm256_set1_ps(max); | ||||||
|  |             __m256 maxValuesIndex = _mm256_setzero_ps(); | ||||||
|  |             __m256 compareResults; | ||||||
|  |             __m256 currentValues; | ||||||
|  |  | ||||||
|  |             __VOLK_ATTR_ALIGNED(32) float maxValuesBuffer[8]; | ||||||
|  |             __VOLK_ATTR_ALIGNED(32) float maxIndexesBuffer[8]; | ||||||
|  |  | ||||||
|  |             for(;number < quarterPoints; number++) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                     currentValues  = _mm256_loadu_ps(inputPtr); inputPtr += 8; | ||||||
|  |                     currentIndexes = _mm256_add_ps(currentIndexes, indexIncrementValues); | ||||||
|  |  | ||||||
|  |                     //compareResults = _mm_cmpgt_ps(maxValues, currentValues); | ||||||
|  |                     compareResults = _mm256_cmp_ps(maxValues, currentValues, 0x1e); | ||||||
|  |  | ||||||
|  |                     maxValuesIndex = _mm256_blendv_ps(currentIndexes, maxValuesIndex, compareResults); | ||||||
|  |                     maxValues      = _mm256_blendv_ps(currentValues, maxValues, compareResults); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             // Calculate the largest value from the remaining 8 points | ||||||
|  |             _mm256_store_ps(maxValuesBuffer, maxValues); | ||||||
|  |             _mm256_store_ps(maxIndexesBuffer, maxValuesIndex); | ||||||
|  |  | ||||||
|  |             for(number = 0; number < 8; number++) | ||||||
|  |                 { | ||||||
|  |                     if(maxValuesBuffer[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = maxIndexesBuffer[number]; | ||||||
|  |                             max = maxValuesBuffer[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             number = quarterPoints * 8; | ||||||
|  |             for(;number < num_points; number++) | ||||||
|  |                 { | ||||||
|  |                     if(src0[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = number; | ||||||
|  |                             max = src0[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |             target[0] = (uint32_t)index; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /*LV_HAVE_AVX*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef LV_HAVE_SSE4_1 | #ifdef LV_HAVE_SSE4_1 | ||||||
| #include<smmintrin.h> | #include<smmintrin.h> | ||||||
|  |  | ||||||
| @@ -125,6 +259,72 @@ static inline void volk_gnsssdr_32f_index_max_32u_a_sse4_1(uint32_t* target, con | |||||||
| #endif /*LV_HAVE_SSE4_1*/ | #endif /*LV_HAVE_SSE4_1*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_SSE4_1 | ||||||
|  | #include<smmintrin.h> | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_32f_index_max_32u_u_sse4_1(uint32_t* target, const float* src0, uint32_t num_points) | ||||||
|  | { | ||||||
|  |     if(num_points > 0) | ||||||
|  |         { | ||||||
|  |             uint32_t number = 0; | ||||||
|  |             const uint32_t quarterPoints = num_points / 4; | ||||||
|  |  | ||||||
|  |             float* inputPtr = (float*)src0; | ||||||
|  |  | ||||||
|  |             __m128 indexIncrementValues = _mm_set1_ps(4); | ||||||
|  |             __m128 currentIndexes = _mm_set_ps(-1,-2,-3,-4); | ||||||
|  |  | ||||||
|  |             float max = src0[0]; | ||||||
|  |             float index = 0; | ||||||
|  |             __m128 maxValues = _mm_set1_ps(max); | ||||||
|  |             __m128 maxValuesIndex = _mm_setzero_ps(); | ||||||
|  |             __m128 compareResults; | ||||||
|  |             __m128 currentValues; | ||||||
|  |  | ||||||
|  |             __VOLK_ATTR_ALIGNED(16) float maxValuesBuffer[4]; | ||||||
|  |             __VOLK_ATTR_ALIGNED(16) float maxIndexesBuffer[4]; | ||||||
|  |  | ||||||
|  |             for(;number < quarterPoints; number++) | ||||||
|  |                 { | ||||||
|  |  | ||||||
|  |                     currentValues  = _mm_loadu_ps(inputPtr); inputPtr += 4; | ||||||
|  |                     currentIndexes = _mm_add_ps(currentIndexes, indexIncrementValues); | ||||||
|  |  | ||||||
|  |                     compareResults = _mm_cmpgt_ps(maxValues, currentValues); | ||||||
|  |  | ||||||
|  |                     maxValuesIndex = _mm_blendv_ps(currentIndexes, maxValuesIndex, compareResults); | ||||||
|  |                     maxValues      = _mm_blendv_ps(currentValues, maxValues, compareResults); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             // Calculate the largest value from the remaining 4 points | ||||||
|  |             _mm_store_ps(maxValuesBuffer, maxValues); | ||||||
|  |             _mm_store_ps(maxIndexesBuffer, maxValuesIndex); | ||||||
|  |  | ||||||
|  |             for(number = 0; number < 4; number++) | ||||||
|  |                 { | ||||||
|  |                     if(maxValuesBuffer[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = maxIndexesBuffer[number]; | ||||||
|  |                             max = maxValuesBuffer[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             number = quarterPoints * 4; | ||||||
|  |             for(;number < num_points; number++) | ||||||
|  |                 { | ||||||
|  |                     if(src0[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = number; | ||||||
|  |                             max = src0[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |             target[0] = (uint32_t)index; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /*LV_HAVE_SSE4_1*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef LV_HAVE_SSE | #ifdef LV_HAVE_SSE | ||||||
|  |  | ||||||
| #include<xmmintrin.h> | #include<xmmintrin.h> | ||||||
| @@ -192,6 +392,73 @@ static inline void volk_gnsssdr_32f_index_max_32u_a_sse(uint32_t* target, const | |||||||
| #endif /*LV_HAVE_SSE*/ | #endif /*LV_HAVE_SSE*/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef LV_HAVE_SSE | ||||||
|  |  | ||||||
|  | #include<xmmintrin.h> | ||||||
|  |  | ||||||
|  | static inline void volk_gnsssdr_32f_index_max_32u_u_sse(uint32_t* target, const float* src0, uint32_t num_points) | ||||||
|  | { | ||||||
|  |     if(num_points > 0) | ||||||
|  |         { | ||||||
|  |             uint32_t number = 0; | ||||||
|  |             const uint32_t quarterPoints = num_points / 4; | ||||||
|  |  | ||||||
|  |             float* inputPtr = (float*)src0; | ||||||
|  |  | ||||||
|  |             __m128 indexIncrementValues = _mm_set1_ps(4); | ||||||
|  |             __m128 currentIndexes = _mm_set_ps(-1,-2,-3,-4); | ||||||
|  |  | ||||||
|  |             float max = src0[0]; | ||||||
|  |             float index = 0; | ||||||
|  |             __m128 maxValues = _mm_set1_ps(max); | ||||||
|  |             __m128 maxValuesIndex = _mm_setzero_ps(); | ||||||
|  |             __m128 compareResults; | ||||||
|  |             __m128 currentValues; | ||||||
|  |  | ||||||
|  |             __VOLK_ATTR_ALIGNED(16) float maxValuesBuffer[4]; | ||||||
|  |             __VOLK_ATTR_ALIGNED(16) float maxIndexesBuffer[4]; | ||||||
|  |  | ||||||
|  |             for(;number < quarterPoints; number++) | ||||||
|  |                 { | ||||||
|  |                     currentValues  = _mm_loadu_ps(inputPtr); inputPtr += 4; | ||||||
|  |                     currentIndexes = _mm_add_ps(currentIndexes, indexIncrementValues); | ||||||
|  |  | ||||||
|  |                     compareResults = _mm_cmpgt_ps(maxValues, currentValues); | ||||||
|  |  | ||||||
|  |                     maxValuesIndex = _mm_or_ps(_mm_and_ps(compareResults, maxValuesIndex) , _mm_andnot_ps(compareResults, currentIndexes)); | ||||||
|  |  | ||||||
|  |                     maxValues      = _mm_or_ps(_mm_and_ps(compareResults, maxValues) , _mm_andnot_ps(compareResults, currentValues)); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             // Calculate the largest value from the remaining 4 points | ||||||
|  |             _mm_store_ps(maxValuesBuffer, maxValues); | ||||||
|  |             _mm_store_ps(maxIndexesBuffer, maxValuesIndex); | ||||||
|  |  | ||||||
|  |             for(number = 0; number < 4; number++) | ||||||
|  |                 { | ||||||
|  |                     if(maxValuesBuffer[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = maxIndexesBuffer[number]; | ||||||
|  |                             max = maxValuesBuffer[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             number = quarterPoints * 4; | ||||||
|  |             for(;number < num_points; number++) | ||||||
|  |                 { | ||||||
|  |                     if(src0[number] > max) | ||||||
|  |                         { | ||||||
|  |                             index = number; | ||||||
|  |                             max = src0[number]; | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |             target[0] = (uint32_t)index; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif /*LV_HAVE_SSE*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| #ifdef LV_HAVE_GENERIC | #ifdef LV_HAVE_GENERIC | ||||||
|  |  | ||||||
| static inline void volk_gnsssdr_32f_index_max_32u_generic(uint32_t* target, const float* src0, uint32_t num_points) | static inline void volk_gnsssdr_32f_index_max_32u_generic(uint32_t* target, const float* src0, uint32_t num_points) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez