【问题标题】:what's the most efficient way to shuffle huge bit-vectors using GCC使用 GCC 洗牌巨大位向量的最有效方法是什么
【发布时间】:2015-01-20 12:15:08
【问题描述】:

我有两个非常大的位向量(每个大约 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++ 中使用新 Intel 处理器的向量运算最有效的方法是什么?我想使用 GCC 来做到这一点。

【问题讨论】:

  • 你试过什么?为什么使用两个 std::vector<bool> 的幼稚循环还不够?
  • 所以你需要创建第三个向量来存储ab的洗牌?
  • 为什么不使用位集而不是位向量,它们更快。
  • @AlexandreC。我做了循环,但工作太慢了。我什么都没试过(我是数学家)。我正在阅读新英特尔处理器指令集的手册,并且我知道可以进行高性能位向量混洗操作,但我对如何使用 GCC 实现这一点感到困惑。非常感谢!
  • 这是一个很好的问题。以下是“标准”解决方案:graphics.stanford.edu/~seander/… — 但是,这些都没有使用新的花哨的矢量扩展,因此它们并不能真正回答您的问题。

标签: c++ performance vectorization


【解决方案1】:

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

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 秒。但是,向循环提供数据可能会降低吞吐量。

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 2011-01-28
    • 2011-06-13
    • 1970-01-01
    • 2022-09-28
    • 2023-03-16
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多