gpt4 book ai didi

c++ - 英特尔 x64 的 GCC 中指向整数的指针对齐

转载 作者:行者123 更新时间:2023-11-30 02:29:44 25 4
gpt4 key购买 nike

我需要从某个内存位置将几个四字加在一起:

uint64_t sum2 (const char * p, size_t n)
{
uint64_t res = 0;
const uint32_t * q = (const uint32_t*) p;
size_t i;
for (i = 0; i < n; i++) res += q[i];
return res;
}

我知道这段代码不必在任意机器上的任意 C 编译器上工作。并非每个指向 char 的指针都可以转换为指向 int 的有效指针。但是,在 Intel 上,您可以从任何地址读取 32 位值,在大多数情况下甚至没有任何性能损失,因此这段代码应该可以正常工作,而不管 p 的对齐方式如何。我的程序在 64 位 Intel Sandy Bridge 上运行,使用 GCC 4.8 使用 -msse4.2 -O3 编译。

本地址不是 4 对齐时,此代码发出 SIGSEGV。原因是循环展开四次并使用 SSE 编译。使用MOVDQA一起读取四个值,需要16位对齐。在循环之前,指针16位对齐,前提是它已经4位对齐。

如何防止 GCC 上的 SSE 优化?我确实需要添加未对齐的 32 位数字。

最佳答案

它可能会降低性能,但我认为您需要使用 memcpy 复制到正确对齐的临时文件。

uint64_t sum2 (const char * p, size_t n)
{
uint64_t res = 0, temp;
const uint32_t * q = (const uint32_t*) p;
size_t i;
for (i = 0; i < n; i++) {
memcpy(&temp, &q[i], sizeof(*q));
res += temp;
}
return res;
}

希望它不会对齐 q&q[i]。如果是这种情况,您需要自己进行地址运算。

uint64_t sum2 (const char * p, size_t n)
{
uint64_t res = 0, temp;
size_t i;
for (i = 0; i < n; i++, p += sizeof(uint32_t)) {
memcpy(&temp, p, sizeof(uint32_t));
res += temp;
}
return res;
}

关于c++ - 英特尔 x64 的 GCC 中指向整数的指针对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39300708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com