如何将此 memcpy 转换为 for?

How to transform this memcpy into a for?

这两者有什么区别?


for (int i = 0; i < numSamples; i++) {
    mData[sampleIndex++] = *buffer++ * (1.0f / 32768);
}

memcpy(&mData[sampleIndex], buffer, (numSamples * sizeof(float)));

如果我理解正确,第一个将 numSamples float 值逐个复制到 mData。第二个,将 numSamples*sizeof(float) 字节复制到 mData。由于我们正在复制 numSaples * number of bytes on float,我认为他们做同样的事情,但第一个实际上在传递给 mData.

之前乘以东西

那么,有没有办法将 memcpy 转换为 for?类似于:

for (int i = 0; i < numSamples * sizeof(float); i++) {
    //What to put here?
}

上下文:

const int32_t   mChannelCount;
const int32_t   mMaxFrames;
int32_t sampleIndex;
float          *mData;
float *buffer;

我从你的 post 得知你想制作一个 memcpy 类似的副本,但使用 for 循环,在这种情况下你只需要使用相同的 for 循环但没有乘法部分:

for (int i = 0; i < numSamples; i++){
    mData[sampleIndex++] = *buffer++;
}

请注意,在给定条件 () 的情况下,memcpy 可能比 for 循环更有效,因此您可能希望保持这种状态。

另一种更为惯用且我认为更好的实现您正在执行的操作的方法是使用 C++ 库提供的方法,如 and 所建议的那样。

免责声明:在我写我的回答时,,既然如此,也归功于他。

What is the difference between these two?

前者对源数组进行计算,同时将结果复制到另一个数组中,每次一个浮点数。

后者不计算,一次将数组字节的内容复制到另一个中。

So, is there a way to transform the memcpy into a for?

是的。这是一种简单的转换方式:

auto dest_c = static_cast<unsigned char*>(mData + sampleIndex);
auto src_c = static_cast<const unsigned char*>(buffer);
auto end = src_c + numSamples * sizeof(float);
for (; src_c < end;) { // or while(src_c < end)
    *dest_c++ = *src_c++;
}

标准函数的实际实现可能更复杂,涉及与复制长序列相关的优化。


由于您似乎不需要 std::memcpy 的通用重新解释方面,也许一个更简单的替代方案就足够了:

auto dest = mData + sampleIndex;
auto src = buffer;
auto end = src + numSamples;
for (; src < end;) {
    *dest++ = *src++;
}

或者另一种标准算法:

std::copy(buffer, buffer + numSamples, mData + sampleIndex);

What is the difference between these two?

for (int i = 0; i < numSamples; i++) {
  mData[sampleIndex++] = *buffer++ * (1.0f / 32768);
}
// and
memcpy(&mData[sampleIndex], buffer, (numSamples * sizeof(float)));

鉴于 * (1.0f / 32768);,这些完全不同。我假设代码比较将比例差异放在一边。 .

  • 重要提示:buffer, sampleIndexfor 循环后有不同的值。

  • 如果 buffer 的类型发生变化,
  • *buffer++ 不需要更改代码。 * sizeof(float) 必须更改代码。可以使用 * sizeof *buffer.

  • mempcy() 是针对该平台优化的代码。 for() 循环只能做这么多。特别是,mempcy() 假设 mData, buffer 不重叠。 for() 循环可能无法进行优化。

  • for 使用 int 索引,而 memcpy() 使用 size_t。对巨大的阵列产生影响。

  • memcpy() 容忍未对齐的指针。 mData[sampleIndex++] = *buffer++ .. 没有。

“第一个复制 numSamples 浮点值到 mData,一个一个。”是不确定的。一个聪明的编译器可能能够根据上下文进行某些并行复制,并且就好像复制已经完成一个一个

Post code/function 的整个块使用这两种方法进行更好的比较。