gpt4 book ai didi

c++ - 在不破坏严格别名的情况下高效生成字节缓冲区

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:56 24 4
gpt4 key购买 nike

这是一个如此简单的模式,必须有一种“好”的方式来整理它。

我有一个函数需要生成一个包含算术数据的动态大小的字节数组。

// Given that I have a function that kinda looks like this:
void dispatch(std::vector<char> data); //Will take possesion of data.

// The behavior I want, but this breaks strict aliasing
void bad_foo(int c) {
std::vector<char> real_data(c * sizeof(float));
float* raw_data = reinterpret_cast<float*>(real_data.data());

//Fill raw_data with usefull stuff...

dispatch(std::move(real_data));
}

void correct_but_slow_foo(int c) {
std::vector<float> raw_data(c);

//Fill raw_data with usefull stuff...

std::vector<char> real_data(c * sizeof(float));
std::memcpy(real_data.data(), raw_data.data(), c * sizeof(float));

dispatch(std::move(real_data));
}

不幸的是,似乎连 clang 的堆省略都无法解决这里需要做的事情:see on godbolt

在最坏的情况下,我可以使 dispatch() 成为一个模板,但这会变得非常困惑,我很好奇是否有解决这个困惑的方法我是无论如何都可以俯瞰。

谢谢!

编辑: 我突然想到一个想法(当然是在发布问题之后......):我可以将 real_data 视为分配池并就地在其上新建算术数据:

void fixed_foo(int c) {
std::vector<char> real_data(c * sizeof(float));
float* raw_data = new (real_data.data()) float[c];

//Fill raw_data with usefull stuff...

dispatch(std::move(real_data));
}

这看起来很时髦,但我“认为”它可能是合法的。也许吧?

最佳答案

绕过别名规则的最安全方法是使用 memcpy() 但您不需要对数据的第二个拷贝执行此操作。我建议您对本地 float 变量执行所有 float 操作,然后将其memcpy() 到您的 中的适当位置>real_data 一次缓冲一个元素。根据我的经验,大多数编译器都会对其进行有效优化。

void better_foo(int c) {
std::vector<char> real_data(c * sizeof(float));

//Fill raw_data with usefull stuff...
for (int i = 0; i < c; ++i) {
float x = my_complicated_calculation(i);
memcpy(&real_data[i * sizeof(float)], &x, sizeof(x));
}

dispatch(std::move(real_data));
}

关于c++ - 在不破坏严格别名的情况下高效生成字节缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46960015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com