我有一个短裤数组,我想在其中获取一半的值并将它们放入一个大小为一半的新数组中。我想以这种模式获取特定值,其中每个块是 128 位(8 个短裤)。这是我将使用的唯一模式,它不需要是“任何通用模式”!
白色的值被丢弃。我的数组大小将始终是 2 的幂。这是它的模糊概念,未矢量化:
unsigned short size = 1 << 8;
unsigned short* data = new unsigned short[size];
...
unsigned short* newdata = new unsigned short[size >>= 1];
unsigned int* uintdata = (unsigned int*) data;
unsigned int* uintnewdata = (unsigned int*) newdata;
for (unsigned short uintsize = size >> 1, i = 0; i < uintsize; ++i)
{
uintnewdata[i] = (uintdata[i * 2] & 0xFFFF0000) | (uintdata[(i * 2) + 1] & 0x0000FFFF);
}
我从这样的事情开始:
static const __m128i startmask128 = _mm_setr_epi32(0xFFFF0000, 0x00000000, 0xFFFF0000, 0x00000000);
static const __m128i endmask128 = _mm_setr_epi32(0x00000000, 0x0000FFFF, 0x00000000, 0x0000FFFF);
__m128i* data128 = (__m128i*) data;
__m128i* newdata128 = (__m128i*) newdata;
我可以使用掩码迭代执行_mm_and_si128
以获取我正在寻找的值,与 结合_mm_or_si128
并将结果放入newdata128[i]
. 但是,我不知道如何将事物“压缩”在一起并删除白色值。看来如果我能做到这一点,我就根本不需要面具了。
怎么可能呢?
无论如何,最终我也想做与此操作相反的操作,并创建一个两倍大小的新数组并在其中展开当前值。
我还将在白色块中插入新值,我必须用原始数据中的每对短裤迭代地计算这些值。这种计算不能向量化,但结果值的插入应该是向量化的。如何将当前值“展开”到新数组中,插入计算值的最佳方法是什么?我是否应该为每个 128 位迭代计算它们并将它们放入自己的临时块(64 位?128 位?),然后做一些事情来批量插入?还是应该将它们直接放置到我的目标__m128i
中,因为它的成本似乎应该等同于放入临时设备?如果是这样,如何在不弄乱我的其他价值观的情况下做到这一点?
我宁愿为此最多使用 SSE2 操作。