我最近修复了一个错误,其中一个__declspec(align(64))结构的成员由于分配结构的内存的方式而未对齐.所以,我正在寻找解决这种情况的方法.
例如,请考虑以下结构:
struct foo {
__declspec(align(64)) int bar[BAZ_LEN];
int baz;
};
Run Code Online (Sandbox Code Playgroud)
如果在堆栈上分配,编译器将负责对齐.如果通过分配malloc(),它将无法工作.如果出于性能或正确性原因(或两者)依赖于其对齐,这将破坏访问bar的代码.
所以,问题是:处理这种情况的最佳方法是什么?在我的情况下struct foo,除了我的组件的"私有"函数之外的所有函数都可以认为是不透明的.
澄清/更新.非常感谢你的答案.我应该事先说过这个问题,但问题是我的struct的用户分配了一大块内存并将其分成多个部分,其中一个中间部分是一个foo_tstructus 数组.该数组的偏移量不是常数,因此对齐起始地址可能没有帮助.我正在寻找一种方法来允许这样使用我的结构,同时保留一些对齐假设.
我现在想到的解决方案(还没试过这个)是添加一个填充成员:
struct foo {
__declspec(align(64)) int bar[BAZ_LEN];
int baz;
char padding[64];
};
Run Code Online (Sandbox Code Playgroud)
并且在每个函数中执行以下操作(包装在宏中):
void f(foo_t *foo_)
{
foo_t *foo = (foo_t *)(((uintptr_t)foo_ & ~63) + 64);
...
}
Run Code Online (Sandbox Code Playgroud)
这会浪费每个结构64个字节,这在我的情况下不是问题.由于从不访问填充成员,因此移位不会导致任何段错误.然而,这个解决方案增加了相当多的心理开销,因为必须为每个公共函数清理对齐...
我需要能够调整构造环境,以便我可以在较低级别构建静态或共享对象.目前,我想出了以下方法:
顶级SConstruct:
if build_shared:
env.Replace(ObjectBuilder = env.SharedObject)
env.Replace(LibraryBuilder = env.SharedLibrary)
else:
env.Replace(ObjectBuilder = env.StaticObject)
env.Replace(LibraryBuilder = env.StaticLibrary)
Run Code Online (Sandbox Code Playgroud)
在较低级别的SConstructs中,我按名称调用它们:
env['ObjectBuilder']('foo.c')
env['LibraryBuilder']('lib', objects)
Run Code Online (Sandbox Code Playgroud)
但是,我不确定这个解决方案有多健全.是否有更简单/正确的方法来实现相同的功能?
提前致谢.