我有一个大致如下所示的类:
template<std::size_t dim>
class Foo {
public:
Foo(void const * const data);
private:
double vals[dim];
}
对于构造函数,我知道 void* data
指向一个 float
值数组(维数为 dim)。现在我想在该构造函数的初始化列表中初始化 vals
-array(最好)。
更糟糕的是,指向的 float 不一定要正确地进行内存对齐。
我怎样才能有效地做到这一点?
编辑1
关于下面进行的讨论,也许让我先陈述一下我的设计重点。这可能会帮助您专注于对我来说最重要的问题。
- 处理错误的内存对齐
- 在性能方面获得尽可能少的操作。
老实说,如果我们需要构造函数体来使算法快速运行,这对我来说也很好。重点是原始功率。
最佳答案
如果您担心传递的指针未与float
边界对齐(例如,文件映射等),那么您可以这样写
template<std::size_t dim>
class Foo {
public:
Foo(void const * const data)
{
float temp[dim];
memcpy( &temp, data, dim * sizeof( float ) );
std::copy( temp, temp + dim, vals );
}
private:
double vals[dim];
}
可能是一个过分热心且不那么便携的解决方案:
template<std::size_t dim>
class Foo {
public:
Foo(void const * const data)
{
if( static_cast<long>( data ) % sizeof( float ) == 0 ) {
const float *temp = data;
std::copy( temp, temp + dim, vals );
} else {
float temp[dim];
memcpy( &temp, data, dim * sizeof( float ) );
std::copy( temp, temp + dim, vals );
}
}
private:
double vals[dim];
}
在初始化列表中初始化不会使您的代码更快,这只是在可能的情况下提供的便利。
如果您非常关心性能,我会将这个 if
包装在一个宏中,并且只在架构上使用 if
,这需要正确对齐的访问(x86 是不是一个,它只是在 x86 上更慢)。
编辑
评论中提出的另一种解决方案,感谢 Steve Jessop .它着重于减少临时变量的大小。
double *dest = vals;
float tmp;
void const *first = data;
void const *last = data + dim * sizeof(float);
while( first != last ) {
memcpy( &tmp, first, sizeof(float) );
first += sizeof(float);
*dest++ = tmp;
}
可能需要进行一些微基准测试/分解。
关于c++ - 在初始化列表中从 float* 设置 double[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6829172/