【问题标题】:SSE Load Neighboring ValuesSSE 加载相邻值
【发布时间】:2014-07-06 21:29:05
【问题描述】:

处理 2D 数组时的常见做法是加载一组值,然后将它们向左或向右移动,然后再将 1 个值加载到不再需要的值中。最好的方法是什么??

float arr[128][128];

for(int i = 1;i < 127;++i)
for(int j = 1;j < 127;++j)
{
 __m128 top = _mm_load_ps(arr[i - 1][j]);
 __m128 center = _mm_load_ps(arr[i][j]);

 //...stuff

 //rotate the top
 top = _mm_shuffle_ps(top,top,_MM_SHUFFLE(0,3,2,1));
 //how do i load another item in without insert?

【问题讨论】:

    标签: c++ x86 sse simd


    【解决方案1】:

    如果您正在谈论对 2D 数据进行邻域运算,那么要获得向左或向右移动一定量的向量,您可以使用未对齐的负载,或者如果您可以假设 SSSE3 或更高版本,请使用 _mm_alignr_epi8。通常,您只会在没有其他选择的 SSE3 或更低版本的旧 CPU 上使用未对齐加载方法。

    对左/右移动 1 个浮点元素的向量进行操作的示例:

    未对齐的负载:

    for (int j = 0; j < 128; j += 4)
    {
        vl = _mm_loadu_ps(&a[i][j-1]);       // left shifted vector
        vm = _mm_load_ps(&a[i][j]);          // middle vector
        vr = _mm_loadu_ps(&a[i][j+1]);       // right shifted vector
    }
    

    _mm_alignr_epi8:

    va = _mm_setzero_ps();
    vb = _mm_load_ps(&a[i][0]); 
    for (int j = 0; j < 128; j += 4)
    {
        vc = _mm_load_ps(&a[i][j+4]); 
        vl = _mm_alignr_epi8(va, vb, sizeof(float));       // left shifted vector
                                                           // middle vector = vb
        vr = _mm_alignr_epi8(vb, vc, 3 * sizeof(float));   // right shifted vector
        va = vb;                                           // shuffle source vectors left by one
        vb = vc;
    }
    

    请注意,当您执行大量具有大量不同班次的邻域运算时,有时临时转置整个数据块会更有效,这样您只需使用行索引,而不必执行水平向量运算,例如以上。

    【讨论】:

      猜你喜欢
      • 2012-03-04
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多