【问题标题】:How to load bytes in a __m128i in a specific position如何在特定位置加载 __m128i 中的字节
【发布时间】:2013-10-16 22:48:10
【问题描述】:

我需要在 __m128i 变量的特定位置加载连续存储在数组中的 4 个字节,即能够进行多次 int32_t 求和,一次 4 个,存储所有部分结果。

例如:

const unsigned int SIZE = 2000000;
const unsigned int STEP = 100;

unsigned char* inBuffer = new char[SIZE];
//Fill inBuffer
const unsigned char* a = inBuffer;

int32_t* outBuffer = new int32_t[SIZE/STEP*4];
int32_t* result = outBuffer;

__m128i sum = _mm_setzero_si128 ()
for (int i = 0; i < SIZE; i+=STEP) {
    __m128i value = _mm_set_epi32 (a[3],a[2],a[1],a[0]);
    sum = __mm_add_epi32(sum,value);
    _mm_storeu_si128 ((__m128i*)result,sum);
    a+=STEP;
    result+=4;
    }

//Print outBuffer

delete[] inBuffer;
delete[] outBuffer;

我想知道是否有更有效的方法来做到这一点

【问题讨论】:

    标签: c++ image-processing x86 sse simd


    【解决方案1】:

    这里的主要问题当然是这一行:

    __m128i value = _mm_set_epi32 (a[3],a[2],a[1],a[0]);
    

    然而,一个体面的编译器应该为此生成相当高效的代码。查看输出 (gcc -O3 -S ...) - 如果它的指令不止几条,那么您可能需要考虑自己执行加载/解包操作。

    【讨论】:

    • 我可以在 __m128i 中仅加载 4 个字节吗? (加载 16 并丢弃 12 听起来效率不高)如果是,我可以将它们洗牌。顺便说一句,是否有可能知道我可以依靠多少个 __m128i 寄存器?任何接近 10 的内容都将有助于我剩下的处理,我可以考虑一次性加载 16 个字节......
    • 如果您可以安排处理连续数据会更好 - 然后您可以一次加载 16 个字节,解压缩并将其处理为 4 x 4 x int32_t。
    • 我在考虑这个!但是我需要 4 个寄存器用于 4 个洗牌掩码,1 个寄存器用于加载数据,1 个寄存器用于数据副本,4 个寄存器用于 16 部分和,这不是太多了吗?
    • 显然太多了,因为使用 32 位应用程序我显然只能访问 8 个寄存器。还是可以继续用3个掩码和3个部分和,每次丢掉4个字节……希望明天有时间试试……
    • 好吧,我意识到我只需要7个寄存器,剩下的我可以用移位操作来做,希望我能尽快尝试:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 2011-08-18
    • 2011-10-08
    相关资源
    最近更新 更多