rewrite of f32 fma, and other optmization of simd kernel ops
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
// ans = left * right + ans
|
||||
// right is not transposed
|
||||
INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left,
|
||||
MAT_KERNEL(float) const *restrict right,
|
||||
MAT_KERNEL(float) *restrict ans)
|
||||
@@ -10,34 +11,47 @@ INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left,
|
||||
register __m128 source2 = _mm_load_ps(&left->xmm[2]);
|
||||
register __m128 source3 = _mm_load_ps(&left->xmm[3]);
|
||||
|
||||
register __m128 ans0 = _mm_load_ps(&ans->xmm[0]);
|
||||
register __m128 ans1 = _mm_load_ps(&ans->xmm[1]);
|
||||
register __m128 ans2 = _mm_load_ps(&ans->xmm[2]);
|
||||
register __m128 ans3 = _mm_load_ps(&ans->xmm[3]);
|
||||
|
||||
register __m128 broadcast;
|
||||
|
||||
register __m128 ans0 = _mm_setzero_ps();
|
||||
register __m128 ans1 = _mm_setzero_ps();
|
||||
register __m128 ans2 = _mm_setzero_ps();
|
||||
register __m128 ans3 = _mm_setzero_ps();
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
broadcast = _mm_load_ps(&right->xmm[i]);
|
||||
_mm_add_ps(ans0, _mm_mul_ps(source0, broadcast));
|
||||
_mm_add_ps(ans1, _mm_mul_ps(source1, broadcast));
|
||||
_mm_add_ps(ans2, _mm_mul_ps(source2, broadcast));
|
||||
_mm_add_ps(ans3, _mm_mul_ps(source3, broadcast));
|
||||
for (size_t t = 0; t < 2; t++) {
|
||||
broadcast = _mm_shuffle_ps(broadcast, broadcast, _MM_SHUFFLE(2, 1, 0, 3));
|
||||
|
||||
_mm_add_ps(ans0, _mm_mul_ps(source0, broadcast));
|
||||
_mm_add_ps(ans1, _mm_mul_ps(source1, broadcast));
|
||||
_mm_add_ps(ans2, _mm_mul_ps(source2, broadcast));
|
||||
_mm_add_ps(ans3, _mm_mul_ps(source3, broadcast));
|
||||
}
|
||||
ans0 = _mm_add_ps(ans0,
|
||||
_mm_mul_ps(source0, _mm_shuffle_ps(broadcast, broadcast, 0x00)));
|
||||
ans1 = _mm_add_ps(ans1,
|
||||
_mm_mul_ps(source1, _mm_shuffle_ps(broadcast, broadcast, 0x55)));
|
||||
ans2 = _mm_add_ps(ans2,
|
||||
_mm_mul_ps(source2, _mm_shuffle_ps(broadcast, broadcast, 0xAA)));
|
||||
ans3 = _mm_add_ps(ans3,
|
||||
_mm_mul_ps(source3, _mm_shuffle_ps(broadcast, broadcast, 0xFF)));
|
||||
}
|
||||
source0 = _mm_load_ps(&ans->xmm[0]);
|
||||
source1 = _mm_load_ps(&ans->xmm[1]);
|
||||
source2 = _mm_load_ps(&ans->xmm[2]);
|
||||
source3 = _mm_load_ps(&ans->xmm[3]);
|
||||
|
||||
_mm_store_ps(&ans->xmm[0], _mm_add_ps(source0, ans0));
|
||||
_mm_store_ps(&ans->xmm[1], _mm_add_ps(source1, ans1));
|
||||
_mm_store_ps(&ans->xmm[2], _mm_add_ps(source2, ans2));
|
||||
_mm_store_ps(&ans->xmm[3], _mm_add_ps(source3, ans3));
|
||||
_mm_store_ps(&ans->xmm[0], ans0);
|
||||
_mm_store_ps(&ans->xmm[1], ans1);
|
||||
_mm_store_ps(&ans->xmm[2], ans2);
|
||||
_mm_store_ps(&ans->xmm[3], ans3);
|
||||
}
|
||||
|
||||
// ans = left * right + ans
|
||||
INTERNAL void SN_DECL f32_fma_avx(MAT_KERNEL(float) const *restrict left,
|
||||
MAT_KERNEL(float) const *restrict right,
|
||||
MAT_KERNEL(float) *restrict ans)
|
||||
{
|
||||
/*
|
||||
* to be implemented
|
||||
*/
|
||||
}
|
||||
|
||||
// ans = left * right + ans
|
||||
INTERNAL void SN_DECL f32_fma_512(MAT_KERNEL(float) const *restrict left,
|
||||
MAT_KERNEL(float) const *restrict right,
|
||||
MAT_KERNEL(float) *restrict ans)
|
||||
{
|
||||
/*
|
||||
* to be implemented
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user