【问题标题】:How can I indicate to the compiler that a pointer parameter is aligned?如何向编译器指示指针参数已对齐?
【发布时间】: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


【解决方案1】:

在 GCC/Clang 中你可以这样做

int *as_ints = __builtin_assume_aligned(a);

或者如果a是函数参数,直接用__attribute((aligned(4)))标记即可。

【讨论】:

  • 1.我可以对函数参数而不是表达式执行此操作吗? 2.clang有这个吗? 3、MSVC有类似的吗?
  • @einpoklum 我添加了有关函数参数和 Clang 的信息,但我对 VS 了解不多。
  • 好的,你得到了 +1。
【解决方案2】:

在 C++20 中你可以使用std::assume_aligned:

#include <memory>

int *as_ints = std::assume_aligned<sizeof(int)>(a);

【讨论】:

    猜你喜欢
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多