gpt4 book ai didi

c - 现代处理器上的内存对齐?

转载 作者:IT王子 更新时间:2023-10-28 23:31:45 25 4
gpt4 key购买 nike

我经常看到如下代码,例如,在内存中表示一个大的位图:

size_t width = 1280;
size_t height = 800;
size_t bytesPerPixel = 3;
size_t bytewidth = ((width * bytesPerPixel) + 3) & ~3; /* Aligned to 4 bytes */
uint8_t *pixelData = malloc(bytewidth * height);

(即,分配为连续内存块的位图,其 bytewidth 与一定数量的字节对齐,最常见的是 4。)

然后通过以下方式给出图像上的一个点:

pixelData + (bytewidth * y) + (bytesPerPixel * x)

这引出了两个问题:

  1. 像这样对齐缓冲区是否会对现代处理器的性能产生影响?我应该担心对齐,还是编译器会处理这个问题?
  2. 如果确实有影响,有人可以指点我找到适合各种处理器的理想字节对齐的资源吗?

谢谢。

最佳答案

这取决于很多因素。如果您一次只访问一个字节的像素数据,则在绝大多数情况下对齐不会产生任何影响。对于读取/写入一个字节的数据,大多数处理器根本不关心该字节是否在 4 字节边界上。

但是,如果您以大于一个字节的单位访问数据(例如,以 2 字节或 4 字节为单位),那么您肯定会看到对齐效果。对于某些处理器(例如许多 RISC 处理器),在某些级别访问未对齐的数据是完全非法的:尝试从非 4 字节对齐的地址读取 4 字节字将产生数据访问异常(或数据存储异常) ) 例如,在 PowerPC 上。

在其他处理器(例如 x86)上,允许访问未对齐的地址,但它通常会带来隐藏的性能损失。内存加载/存储通常在微码中实现,微码会检测未对齐的访问。通常,微码会从内存中获取正确的 4 字节数量,但如果未对齐,则必须从内存中获取 两个 4 字节位置,并从两个位置的适当字节。获取两个内存位置显然比一个慢。

不过,这只是用于简单的加载和存储。某些指令,例如 MMX 或 SSE 指令集中的指令,要求它们的内存操作数正确对齐。如果您尝试使用这些特殊指令访问未对齐的内存,您会看到类似非法指令异常的情况。

总而言之,除非您正在编写 super 性能关键代码(例如在汇编中),否则我不会太担心对齐问题。编译器可以帮助您很多,例如通过填充结构使 4 字节数量在 4 字节边界上对齐,并且在 x86 上,CPU 还可以帮助您处理未对齐的访问。由于您处理的像素数据为 3 个字节,因此您几乎总是在进行单字节访问。

如果您决定改为以单个 4 字节访问(而不是 3 个 1 字节访问)来访问像素,最好使用 32 位像素并将每个单独的像素对齐在 4 字节上边界。将每一行与 4 字节边界对齐,但不是每个像素都将产生很小的影响(如果有的话)。

根据您的代码,我猜它与读取 Windows 位图文件格式有关——位图文件要求每个扫描线的长度是 4 个字节的倍数,因此使用该属性设置像素数据缓冲区有您可以一口气读入整个位图的属性(当然,您仍然必须处理扫描线是从下到上而不是从上到下存储的事实,并且像素数据是 BGR 而不是 RGB)。不过,这并不是一个真正的优势——在位图中一次读取一条扫描线并不难。

关于c - 现代处理器上的内存对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1855896/

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