Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 获取处理器的内存粒度_C_Memory Management_Memory Alignment_Granularity - Fatal编程技术网

C 获取处理器的内存粒度

C 获取处理器的内存粒度,c,memory-management,memory-alignment,granularity,C,Memory Management,Memory Alignment,Granularity,如何在C中获得CPU的性能 假设我想分配一个数组,其中所有元素都正确地对齐内存。我可以将每个元素填充到特定的大小N来实现这一点。我如何知道N的值 注意:我正在尝试创建一个内存池,其中每个插槽都是内存对齐的。任何建议都将不胜感激。这在很大程度上取决于您使用的cpu微体系结构 在许多情况下,运算符的内存地址应该是操作数大小的倍数,否则执行会很慢(甚至可能引发异常) 但也有一些CPU根本不关心内存中操作数的特定对齐方式 通常,C编译器会为您关心这些细节。但是,您应该确保编译器采用正确的目标(微)体系结

如何在C中获得CPU的性能

假设我想分配一个数组,其中所有元素都正确地对齐内存。我可以将每个元素填充到特定的大小N来实现这一点。我如何知道N的值


注意:我正在尝试创建一个内存池,其中每个插槽都是内存对齐的。任何建议都将不胜感激。

这在很大程度上取决于您使用的cpu微体系结构

在许多情况下,运算符的内存地址应该是操作数大小的倍数,否则执行会很慢(甚至可能引发异常)

但也有一些CPU根本不关心内存中操作数的特定对齐方式

通常,C编译器会为您关心这些细节。但是,您应该确保编译器采用正确的目标(微)体系结构,例如通过使用正确的编译器标志(
-march=?
在gcc上)来指定它。

理论上 如何在C中获得CPU的内存粒度

首先,阅读指令集体系结构手册。它可能指定某些指令需要某些对齐,甚至某些指令中的寻址形式不能表示非对齐地址。它可以指定有关对齐的其他属性

其次,您要阅读处理器手册。它可以指定性能特征(例如支持未对齐的加载或存储,但可能比对齐的加载或存储慢或使用更多的资源),并且可以指定指令集体系结构允许的各种选项

第三,阅读操作系统文档。某些体系结构允许操作系统选择与对齐相关的功能,例如是否使未对齐的加载和存储失败或受支持,尽管性能比对齐的加载或存储慢。操作系统文档应包含此信息

实际上 对于许多编程情况,您需要知道的不是CPU的“内存粒度”,而是您正在使用的C实现(或您正在使用的任何语言)的对齐要求。而且,在大多数情况下,您不需要直接了解对齐要求,只需要遵循有关管理对象的语言规则使用声明类型的对象,不要使用强制转换在不兼容类型之间转换指针,如果特定规则允许,使用
malloc
提供的适当对齐的内存,而不是将自己的指针调整为字节,等等。遵循这些规则将为程序中的对象提供良好的对齐

在C中,定义数组时,元素大小将自动成为C实现对齐所需的大小。例如,
long double x[100]
可以为每个数组元素使用16个字节,即使硬件仅为
长双精度
使用10个字节。或者,对于您定义的任何
struct foo
,编译器将根据需要在结构中自动包含填充,以提供所需的对齐方式,以及任何数组
struct foo x[100]将已经包含该填充
sizeof(struct foo)
将与
sizeof x[0]
相同,因为每个结构对象都内置了填充,即使是针对单个结构对象,而不仅仅是针对数组中的元素

当您确实需要知道C实现对类型要求的对齐方式时,可以使用C的
\u Alignof
运算符。表达式
\u Alignof(type)
提供了
type
所需的对齐方式

其他 …正确对齐内存

正确对齐是程度的问题:

  • 处理器支持的内容可能决定程序是否工作。不正确的对齐会导致程序陷井
  • 关于单个加载和存储的效率可能会影响程序的运行速度。不正确的对齐会导致程序执行速度变慢
  • 在某些性能关键的情况下,与缓存和内存映射功能的一致性也会影响性能
简短回答 使用64字节

长话短说 数据以称为缓存线的单位从内存加载并存储到内存中。如果您的程序只加载缓存线中的部分数据,那么整个缓存线将加载到CPU缓存中。也许更重要的是,多核CPU中的内存在全缓存线上运行;将数据与缓存线对齐可以避免错误共享,即缓存线在内核之间反弹,因为它包含由不同线程操作的数据


过去的情况是缓存线取决于体系结构,从16字节到512字节不等。但是,当前所有处理器(英特尔、AMD、ARM、MIPS)都使用64字节的缓存线。

编译器和内存管理器(malloc等)将为您提供这一功能。有趣的问题与C的一个基础:可移植性相冲突。正如@PaulOgilvie所说,该代码被认为与处理器体系结构无关,所有特定于端口的调整都是在依赖于编译器端口的代码中完成的。无论如何,在某些情况下,这可能是对特定于机器的代码的真正要求,如在极端效率实现问题或板开发中。不幸的是,C语言对此没有任何标准支持。您必须使用旧的条件编译,使用
#if/#else/#endif
。您的问题不清楚。有单词对齐(对于单个对象),有页面对齐(对于MMU/VM),还有缓存对齐(多个级别)。根据架构的不同,所有这些都可能存在或不存在。另一个稍微无关的问题:如果一个数据不适合一条缓存线,并且需要两条缓存线,那么cpu必须读取两次。因此,数据是否对齐并不重要。会的