标签:c performance sse
我有一个简单的问题.具有起始uint_32值(比如125)和要添加的__m128i操作数,例如(5,10,-1,-5).我想尽可能快地得到一个向量(125 5,125 5 10,125 5 10 -1,125 5 10 -1-5),即从操作数累加值到起始值.到目前为止,我能想到的唯一解决方案是添加4个__m128i变量.例如,他们会
/* pseudoSSE code... */
__m128i src = (125,125,125,125)
__m128i operands =(5,10,-1,-5)
/* Here I omit the partitioning of operands into add1,..add4 for brevity */
__m128i add1 = (+05,+05,+05,+05)
__m128i add2 = (+00,+10,+10,+10)
__m128i add3 = (+00,+00,-01,-01)
__m128i add4 = (+00,+00,+00,-05)
__m128i res1 = _mm_add_epu32( add1, add2 )
__m128i res2 = _mm_add_epu32( add3, add4 )
__m128i res3 = _mm_add_epu32( res1, add2 )
__m128i res = _mm_add_epu32( res3, src )
像这样,我得到了我想要的东西.对于此解决方案,我将需要设置所有add_变量,然后执行4次添加.我真正想问的是,这是否可以更快完成.要么通过一些不同的算法,要么使用一些我还不知道的专门的SSE函数(类似于_mm_cumulative_sum()).非常感谢.
解决方法:
您可以添加更多并行性并使用3个添加而不是4:
const __m128i src = _mm_set1_epi32(125);
const __m128i operands = _mm_set_epi32(5,10,-1,-5);
const __m128i shift1 =
_mm_add_epi32(operands,
_mm_and_si128(_mm_shuffle_epi32(operands, 0xF9),
_mm_set_epi32(0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF)));
const __m128i shift2 =
_mm_add_epi32(shift1,
_mm_and_si128(_mm_shuffle_epi32(shift1, 0xFE),
_mm_set_epi32(0,0,0xFFFFFFFF,0xFFFFFFFF)));
const __m128i res = _mm_add_epi32(src, shift2);
这里使用SSE2指令集.使用较新的指令集,您可以使用_mm_shuffle_epi8等单个指令替换_mm_and_si128 / _mm_shuffle_epi32.
累计总和计算为2个添加项,如下所示:
a b c d
+ a b c
------------------
a a+b b+c c+d
+ a a+b
------------------
a a+b a+b+c a+b+c+d
SSE不适合这样的任务.它的性能仅适用于“垂直”操作,但它需要大量额外的“水平”操作工作,这里需要它.
标签:c,performance,sse 来源: https://codeday.me/bug/20190826/1726036.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。