我突然想到一定有一种聪明的方法可以做到这一点。这不是为了家庭作业,或工作或任何东西。我只是在研究一种数据交错的文件格式。
因此,在通用 C/C++ 中,(或其他)给定一些数组
int x[] = ...
有没有巧妙的方法将它分成两个短数组
short sa1[], sa2[]
使得 int 数组从中间 split
x[i] = 1111111111111111 1111111111111111
sa1[i] sa2[i]
编辑:抱歉,如果措辞不当。对于 int 数组的每个第 i 个元素,最左边的 16 位成为一个数组的第 i 个元素,最右边的 16 位成为第二个数组的第 i 个元素。
如此给定
x[i] = 0001111111111111 1111111100011111
然后
sa1[i] = 0001111111111111
sa2[i] = 1111111100011111
我正在寻找不在每个元素上循环并移动和屏蔽每个元素的非显而易见的答案。这很容易:)
最佳答案
有很多方法可以做到这一点:
假设:
short
是 16 位。int
是 32 位。
方法一:(一个简单的循环)
for (int i = 0; i < size; i++){
int tmp = x[i];
sa1[i] = (tmp ) & 0xffff;
sa2[i] = (tmp >> 16) & 0xffff;
}
方法二:SSE2
for (int i = 0; i < size / 8; i++){
__m128i a0 = ((__m128i*)x)[2*i + 0];
__m128i a1 = ((__m128i*)x)[2*i + 1];
a0 = _mm_shufflelo_epi16(a0,216);
a1 = _mm_shufflelo_epi16(a1,216);
a0 = _mm_shufflehi_epi16(a0,216);
a1 = _mm_shufflehi_epi16(a1,216);
a0 = _mm_shuffle_epi32(a0,216);
a1 = _mm_shuffle_epi32(a1,216);
((__m128i*)sa1)[i] = _mm_unpacklo_epi64(a0,a1);
((__m128i*)sa2)[i] = _mm_unpackhi_epi64(a0,a1);
}
如果进一步展开循环,最后一个例子会非常快。如果这可以击败所有字节操作库,我不会感到惊讶。
但是,它有以下限制:
- 数据必须对齐到 16 字节。
- 迭代次数必须能被 8 整除。
- 它需要 SSE2。
前两个可以通过清理代码解决。这很困惑,但如果您真的想要性能,那可能是值得的。
编辑:
是的,这违反了严格别名,但不这样做几乎不可能使用 SSE 内在函数。
关于c++ - 给定一个整数数组,将数组从中间拆分为两个短数组的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7550102/