【问题标题】:Fast copying contiguous array of arrays快速复制连续的数组数组
【发布时间】:2021-02-21 21:51:03
【问题描述】:

我正在尝试从一个数组数组复制到另一个数组,同时在目标中的数组之间留一个空格。

它们都是连续的,每个向量的大小都在 5000 到 52000 个浮点数之间,
output_jump 是向量大小的八倍,并且vector_count 在我的测试中有所不同。

我在https://stackoverflow.com/a/34450588/1238848https://stackoverflow.com/a/16658555/1238848 学到了最好的东西

但它仍然看起来很慢。

void copyToTarget(const float *input, float *output, int vector_count, int vector_size, int output_jump)
{
    int left_to_do,offset;
    constexpr int block=2048;
    constexpr int blockInBytes = block*sizeof(float);
    float temp[2048];

    for (int i = 0; i < vector_count; ++i)
    {
        left_to_do = vector_size;
        offset = 0;
        while(left_to_do > block)
        {
            memcpy(temp, input, blockInBytes);
            memcpy(output, temp, blockInBytes);
            left_to_do -= block;
            input += block;
            output += block;
        }

        if (left_to_do)
        {
            memcpy(temp, input, left_to_do*sizeof(float));
            memcpy(output, temp, left_to_do*sizeof(float));
            input += left_to_do;
            output += left_to_do;
        }

        output += output_jump;
    }
}

【问题讨论】:

  • 为什么您认为在将整个内容再次复制到目标之前复制到temp 变量比从源直接复制到目标要快?是什么让您得出这样的结论,即制作多个小副本,一次一小块,比只制作一个 memcpy 更快,因为一切都是连续的?
  • 如果涉及到std::vector,这会容易得多。它们具有内置长度,因此不需要额外的参数。你也可以简单地将std::vectora + b 结合起来。
  • 复制到temp 是没有意义和浪费的。摆脱它,你的速度就会翻倍。
  • 你为什么手动将你的复制分成 2,048 个浮点数块?我确信memcpy 可以一次性处理所需的大小。
  • but still it seems so slow. 你的尝试是比普通 memcpy 快还是慢?

标签: c++ arrays memcpy


【解决方案1】:

我对 the answer you linked 持怀疑态度,它鼓励避免对 memcpy 的函数调用。当然,memcpy 的实现非常优化,可能是用汇编手写的,因此很难被击败!此外,对于大型副本,与内存访问延迟相比,函数调用开销可以忽略不计。因此,简单地调用 memcpy 可能是在内存中复制连续字节的最快方法。

如果 output_jump 为零,则对 memcpy 的一次调用可以将input 直接复制到output(这很难被击败)。对于非零 output_jump,副本需要在连续向量上进行分割。每个向量使用一个 memcpy,不使用临时缓冲区,直接从 input + i * vector_size 复制到 output + i * (vector_size + output_jump)

但更好的是,就像该线程上的 top answer 所建议的那样,如果可能的话,首先尝试找到一种避免复制数据的方法。

【讨论】:

    猜你喜欢
    • 2019-04-27
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2018-05-21
    • 2016-11-14
    相关资源
    最近更新 更多