【发布时间】:2017-08-19 21:47:00
【问题描述】:
我正在编写壮观的函数:
void foo(void* a) {
if (check_something_at_runtime_only()) {
int* as_ints { a };
// do things with as_ints
}
else {
char* as_chars { a };
// do things with as_chars
}
}
假设我们知道使用as_ints 的某些工作将受益于它的更好对齐;例如如果我平台上的内存事务大小为 N 字节,那么我可以使用单个机器指令读取前 N/sizeof(int) 元素(此处忽略 SIMD/矢量化) - 前提是 a 是 N 字节对齐的。
现在,我可以通过让 foo 始终采用 int * 来指示对齐 - 至少在只能从对齐地址读取较大类型的平台上 - 但我宁愿保留类型 void *,因为它不一定是ints 的数组,真的。
我希望能够写出类似的东西
void foo(alignas(sizeof(int)) void* a) { ... }
但是,显然,alignas doesn't apply to pointers,所以我不能。
除了参数地址对齐之外,还有其他方法可以向编译器保证吗?
注意事项:
- 我对 C++ 标准(任何版本)所允许的内容以及 GCC、clang 和 NVCC(CUDA 编译器)中特定于编译器的扩展都感兴趣。
【问题讨论】:
-
您似乎本末倒置,它是对齐的指针。您不能强制系统将一个地址视为对齐而不是对齐。你唯一能做的就是调整地址。
-
@StoryTeller:我不确定我理解你的意思。我想告诉编译器“
a可以是0x1004,但不能是0x1002(对于4 字节大小的int)。我知道,理论上,你可以调用foo(0x1002)-但我想向编译器保证这实际上不会发生 - 类似于我们使用__restrict__所拥有的。 -
__restrict__是一个完全不同的野兽,它没有单独使用的指针。如果您知道指针的对齐方式是一回事,您可以使用__builtin_unreachable 提示优化器。答案是关于整数范围,但我相信你可以创建一个关于对齐的条件。 -
这看起来是一个完美的模板候选者。然后整个问题或多或少地消失了。我同意第一条评论,这看起来像是对齐问题的从后到前的视图
-
@talonmies:问题是,有时你不能模板,例如如果您使用的是从库中动态加载的代码,或者您使用的类型只能在运行时确定;看我的编辑。不过,问题只是关于指示对齐,而不是关于
foo()函数。
标签: c++ gcc cuda memory-alignment nvcc