这不是询问 struct 填充/填充, struct 填充/填充指的是出于对齐目的而插入到 struct 中的任何未命名字节.
我有这个功能:
#include <stdint.h>
uint8_t get_index(const uint8_t xs, const uint8_t zs, const uint8_t ys, const uint8_t l) {
return (xs >> l & 1) | (zs >> l & 2) | (ys >> l & 4);
}
令我惊讶的是,尽管由于发出了多个and
和sar
指令而启用了优化,但仍有GCC does not seem to use any SWAR for this条指令.
但我认为我可以像这样简单地实现Swar:
#include <stdint.h>
union Arg {
uint8_t b[3];
uint32_t u;
};
uint8_t get_index(union Arg arg, const uint8_t l) {
static const union Arg mask = {.b = {1, 2, 4}};
/* Using this instead of an integer constant makes the behavior not depend on endianness.
This will be optimized into the appropriate integer constant anyway. */
arg.u = arg.u >> l & mask.u;
return arg.b[0] | arg.b[1] | arg.b[2];
}
正如预期的那样,程序集实际上更短:Version 1 Version 2 Version 3(都是一样的)
- 为什么GCC没有把前者优化为后者?有什么特别的原因吗?或者这只是一次错过的优化?
- 单个字节参数的访问方式是否与
struct
/union
中的字节不同?如果是,原因是什么?我的直觉告诉我,它们不应该是这样的,因为无论哪种方式,它们都位于当前堆栈帧中的已知位置. - 有什么理由这样做会比单独通过它们更慢呢?
我已经看过了:Passing many variables vs. passing struct,但这个问题更多地集中在比CPU字长大得多的大型 struct 上,而我的对象只有4个字节.这些也没有解决访问字内的各个字节的问题.