什么是使用GCC重排大量位向量的最有效方法

时间:2014-11-22 11:21:11

标签: c++ performance vectorization

我有两个非常大的位向量(每个大约1 GB),我想要将它们洗牌 以下列方式:

第一位向量:a[0], a[1], a[n]
第二位向量:b[0], b[1], b[n]

它应该导致类似:

c[0] = a[0]
c[1] = b[0] 
c[2] = a[1]
c[3] = b[1]

使用新英特尔处理器的矢量运算,在C ++中最有效的方法是什么?我想用GCC做到这一点。

1 个答案:

答案 0 :(得分:0)

您可以尝试滚动自己的循环 -

int ch1, ch2;
while ((ch1 = fgetc(fp1)) != EOF && (ch2 = fgetc(fp2)) != EOF) {
    int i, dst = 0;
    // assuming msb goes first
    for (i=7; i>=0; i--) {
        dst |= (ch1 & (1<<i)) << (2*i + 1);
        dst |= (ch2 & (1<<i)) << (2*i + 0);
    }
    putc(dst >> 8);
    putc(dst & 0xFF);
}

你可以按下这一点,展开它,预取块到本地数组,在循环中处理16位,但是它在每个源位4个指令的两个字节中交错(-O3展开循环)。

如果我们假设在3GHz处理器上有两个字节需要150个周期,那么从2x20 MB /秒源数据读取时输出为40 MB /秒,对于2x1000 MB则为50秒。然而,将数据馈送到循环可能会降低吞吐量。