C /SSE代码的有效霓虹灯内在
Efficient NEON intrinsics for C++/SSE code
如何有效地将以下代码段转换为霓虹灯内在?
C
int diff_scale, c0, c1;
cost = (short)(cost + std::min(c0, c1) >> diff_scale));
SSE
__m128i ds = _mm_cvtsi32_si128(diff_scale);
__m128i c0 = _mm_load_si128((__m128i*)(cost));
__m128i c1 = _mm_load_si128((__m128i*)(cost + 8));
__m128i z = _mm_setzero_si128();
_mm_store_si128((__m128i*)(cost), _mm_adds_epi16(c0, _mm_srl_epi16(_mm_unpacklo_epi8(diff, z), ds)));
_mm_store_si128((__m128i*)(cost + 8), _mm_adds_epi16(c1, _mm_srl_epi16(_mm_unpackhi_epi8(diff, z), ds)));
SSE看起来应该是这样的:
int8x16_t ds = vdupq_n_s8(-diff_scale);
int16x8_t c0 = vld1q_s16(cost);
int16x8_t c1 = vld1q_s16(cost + 8);
uint8x16_t diff_ds = vshlq_u8(diff, ds);
#if defined(MAY_SATURATE)
vst1q_s16(cost, vqaddq_s16(c0, vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(diff_ds)))));
vst1q_s16(cost + 8, vqaddq_s16(c1, vreinterpretq_s16_u16(vmovl_u8(vget_high_s8(diff_ds)))));
#else
vst1q_s16(cost, vreinterpretq_s16_u16(vaddw_u16(vreinterpretq_u16_s16(c0), vget_low_u8(diff_ds))));
vst1q_s16(cost + 8, vreinterpretq_s16_u16(vaddw_u16(vreinterpretq_u16_s16(c1), vget_high_s8(diff_ds))));
#endif
C 需要向向量推断出某种外推...也许是这样的?:
int diff_scale, c0[8], c1[8];
int32x4_t ds = vdupq_n_s32(-diff_scale);
int32x4_t c0lo = vld1q_s32(c0);
int32x4_t c0hi = vld1q_s32(c0 + 4);
int32x4_t c1lo = vld1q_s32(c1);
int32x4_t c1hi = vld1q_s32(c1 + 4);
int16x8_t c = vld1q_s16(cost);
c0lo = vshlq_s32(vaddw_s32(vminq_s32(c0lo, c1lo), vget_low_s16(c), ds);
c0hi = vshlq_s32(vaddw_s32(vminq_s32(c0hi, c1hi), vget_high_s16(c), ds);
vst1q_s16(cost, vcombine_s16(vmovn_s16(c0lo), vmovn_s16(c0hi)));
如果 diff_scale
是常数,那么这是:
const int diff_scale = 1;
int c0[8], c1[8];
int32x4_t c0lo = vld1q_s32(c0);
int32x4_t c0hi = vld1q_s32(c0 + 4);
int32x4_t c1lo = vld1q_s32(c1);
int32x4_t c1hi = vld1q_s32(c1 + 4);
int16x8_t c = vld1q_s16(cost);
c = vcombine_s16(vshrn_n_s32(vaddw_s32(vminq_s32(c0lo, c1lo), vget_low_s16(c), diff_scale),
vshrn_n_s32(vaddw_s32(vminq_s32(c0hi, c1hi), vget_high_s16(c), diff_scale));
vst1q_s16(cost, c);
尽管这些看起来都可以使它们变得更简单。
相关文章:
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 为什么这种直接初始化有效?(C++17)
- 递归函数有效,但无法记忆
- 在C++中初始化向量映射的最有效方法
- 如果变量名称不跟在 char* 后面,const char* 是否有效?
- 钳制迭代器是否有效
- 在手臂霓虹灯中有效地重新洗牌和组合 16 个 3 位数字
- 在手臂霓虹灯中有效地组合面膜
- 在手臂霓虹灯中有效地积累符号位
- C /SSE代码的有效霓虹灯内在