使用 GCC 对大型位向量进行洗牌的最有效方法是什么

what's the most efficient way to shuffle huge bit-vectors using GCC

本文关键字:有效 是什么 方法 GCC 大型 向量 使用      更新时间:2023-10-16

我有两个非常大的位向量(每个大约 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 来做到这一点。

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

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 秒。 但是,将数据馈送到循环可能会降低吞吐量。