问题标签 [memory-alignment]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C 中的消息调度系统不会破坏严格的别名和对齐
我正在用 C 编写一个嵌入式控制系统,该系统由多个相互发送消息的任务组成(我相信这是一个相当常见的习语!),但我很难设计一种机制:
- 很整洁
- 是通用的
- 是相对有效的
- 最重要的是:独立于平台(具体来说,不违反严格混叠或对齐问题)
从概念上讲,我想将每种消息类型表示为一个单独的结构定义,并且我想要一个具有以下功能(简化)的系统:
其中 aqueue_t
包含一个节点的链接列表,每个节点都有一个char buf[MAX_SIZE]
字段。我所在的系统没有malloc()
实现,因此需要一个全局空闲节点池,然后是以下之一(以粗体表示的感知问题):
sendMsg()
将memcpy
传入消息的一部分放入空闲节点的缓冲区中。我的理解是,除非调用者对返回值进行进一步
处理,否则这将存在对齐问题。dequeueMsg()
memcpy
- 或者会有一个
void *getFreeBuffer()
返回buf[]
下一个空闲节点的函数,调用者(发送者)将把它转换为适当的指针类型。
我的理解是,现在这将在进入的过程中出现对齐问题,并且仍然需要稍后才能避免memcpy
在dequeueMsg()
退出时出现对齐问题。 - 或将节点中的缓冲区重新定义
queue_t
为 (eg)uint32_t buf[MAX_SIZE]
。
我的理解是这违反了严格的别名,并且不是独立于平台的。
我能看到的唯一其他选择是创建所有消息类型的联合以及char buf[MAX_SIZE]
,但我不认为这是“整洁”!
所以我的问题是,如何正确地做到这一点?
winapi - 原子 x86 指令与 MS 的 InterlockedCompareExchange 文档的对齐要求?
Microsoft 提供了InterlockedCompareExchange
执行原子比较和交换操作的功能。还有一个内在的。_InterlockedCompareExchange
在 x86 上,这些是使用lock cmpxchg
指令实现的。
但是,通过阅读有关这三种方法的文档,他们似乎并没有就对齐要求达成一致。
英特尔的参考手册没有提到对齐(除了如果启用对齐检查并进行未对齐的内存引用,则会生成异常)
我还查找了lock
前缀,其中明确指出
LOCK 前缀的完整性不受内存字段对齐的影响。
(强调我的)
所以英特尔似乎说对齐是无关紧要的。无论如何,操作都是原子的。
_InterlockedCompareExchange
内在文档也没有说明对齐,但是该InterlockedCompareExchange
函数指出
此函数的参数必须在 32 位边界上对齐;否则,该函数将在多处理器 x86 系统和任何非 x86 系统上运行不可预测。
那么给了什么?对齐要求是否InterlockedCompareExchange
只是为了确保该功能即使在cmpxchg
指令不可用的 486 之前的 CPU 上也能正常工作?根据上述信息,这似乎很可能,但在我依赖它之前我想确定一下。:)
或者ISA是否需要对齐来保证原子性,而我只是在英特尔的参考手册中寻找错误的地方?
pointers - 内存 (sbrk) 指针访问时 16 字节对齐移位
我使用 sbrk 编写了一个相当基本的内存分配器。我要求一块内存,比如 65k,并根据需要将其划分为请求动态内存的变量。我通过将内存添加回 65k 块来释放内存。65k 块源自 union sizeof(16-bytes)。然后我将块沿偶数 16 字节边界对齐。但我有不寻常的行为。
当我分配并开始填充我的数据结构时,访问内存看起来不错该成员的地址。
例如,这个特定成员的真实地址恰好是:0x100313d50,但在执行特定函数(没有什么特别之处)时,该成员的地址被表示为 0x100313d70。在调试器内部,我可以查询真实地址,并且在它出现的函数内部时它看起来是正确的。这也不是第一个被访问的成员,它是第三个,所以之前的两次内存访问都很好,但是在第三次访问期间,我看到了这种不寻常的转变。
我是否有可能通过未对齐的块访问此内存?这是可能的,但我希望会引发 SIGBUS 异常(SPARC 芯片)。我正在使用 -memalign=16s 进行编译,因此它应该使用 SIGBUS 而不是捕获和修复错位。
我所有的结构都填充在 16 字节的倍数上:sizeof(structure)%16 = 0。有没有人有过这种行为的经验?一般来说,什么类型的东西/东西/等等。可能会导致指针错误表示内存地址?
干杯,特蕾西。
现代 SPARC 处理器上的 Solaris 10、SunStudio-12、C 语言(如果有帮助的话)。
c - 未对齐的内存访问是否总是会导致总线错误?
根据维基百科页面Segmentation fault,未对齐的内存访问可能会导致总线错误。本文给出了一个关于如何触发总线错误的示例。在示例中,我们必须启用对齐检查才能查看总线错误。如果我们禁用这种对齐检查怎么办?
该程序似乎运行正常。我有一个程序经常访问未对齐的内存,它被很多人使用,但没有人向我报告总线错误或其他奇怪的结果。如果我们禁用对齐检查,未对齐内存的副作用是什么?
平台:我正在研究x86 / x86-64。我还通过在 Mac 上使用“gcc -arch ppc”编译它来尝试我的程序,它可以正常工作。
c++ - 缓存行对齐(需要在文章中说明)
我最近在我的应用程序中遇到了我认为是错误共享的问题,我查阅了Sutter关于如何将我的数据与缓存行对齐的文章。他建议使用以下 C++ 代码:
我可以看到这是如何工作CACHE_LINE_SIZE > sizeof(T)
的——结构cache_line_storage
最终占用了一个完整的缓存行内存。但是,当sizeof(T)
大于单个缓存行时,我认为我们应该按CACHE_LINE_SIZE - T % CACHE_LINE_SIZE
字节填充数据,以便生成的结构的大小是缓存行大小的整数倍。我的理解有什么问题?为什么用 1 个字节填充就足够了?
delphi - 如何确保 Delphi 例程的 16 字节代码对齐?
背景:
我有一个优化的 Delphi/BASM 例程单元,主要用于繁重的计算。其中一些例程包含内部循环,如果循环开始与 DQWORD(16 字节)边界对齐,我可以实现显着的加速。如果我知道例程入口点的对齐方式,我可以确保有问题的循环按照需要对齐。
据我所知,Delphi 编译器将过程/函数与 DWORD 边界对齐,例如,向单元添加函数可能会改变后续函数的对齐方式。但是,只要我将例程的末尾填充为 16 的倍数,我就可以确保后续例程同样对齐 - 或未对齐,具体取决于第一个例程的对齐方式。因此,我尝试将关键例程放在单元实现部分的开头,并在它们之前放置一些填充代码,以便第一个过程与 DQWORD 对齐。
这看起来像下面这样:
这有点让人头疼,但我可以在必要时让这种事情发挥作用。问题是当我在不同的项目中使用这样的单元,或者在同一个项目中对其他单元进行一些更改时,这可能仍然会破坏__PadFirstProcTo16
自身的对齐。同样,使用不同编译器版本(例如 D2009 与 D2010)重新编译同一项目通常也会破坏对齐。所以,我发现做这种事情的唯一方法是当项目的所有其余部分都处于最终形式时,手工几乎是最后要做的事情。
问题一:
是否有任何其他方法可以实现确保(至少某些特定)例程与 DQWORD 对齐的预期效果?
问题2:
哪些是影响编译器代码对齐的确切因素,(如何)我可以使用这些特定知识来克服这里列出的问题?
假设为了这个问题,“不要担心代码对齐/相关的可能很小的速度优势”不是一个允许的答案。
c++ - SSE2 - 16 字节对齐的动态内存分配
编辑:
这是我之前遇到的真正错误,并通过更改Michael Burr建议的_mm_malloc
语句在下面复制:
SO.exe 中 0x00415116 处的未处理异常:0xC0000005:访问冲突读取位置 0xffffffff。
在线label: movdqa xmm0, xmmword ptr [t1+eax]
我正在尝试动态分配t1
,t2
并且根据本教程,我使用过_mm_malloc
:
c - GCC 中的 C 函数对齐
我正在尝试使用 'aligned(16)' 属性将函数字节对齐到 16 字节边界。我做了以下事情: void __attribute__((aligned(16))) function() { }
(来源: http: //gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html)
但是当我编译(gcc foo.c ;没有使用 makefile 或链接器脚本)时,我收到以下错误:
FOO.c:99:错误:可能未为“功能”指定对齐方式
我也尝试对齐到 4、8、32 等,但错误仍然相同。我需要它来为基于 powerpc 的处理器对齐中断服务例程。这样做的正确方法是什么?
c - 如何在 C 中分配和释放对齐的内存
您如何分配与 C 中特定边界对齐的内存(例如,高速缓存行边界)?我正在寻找类似 malloc/free 的实现,它在理想情况下会尽可能地便携——至少在 32 位和 64 位架构之间。
编辑添加:换句话说,我正在寻找一些行为类似于(现在已经过时?)memalign函数,可以使用 free 释放。
performance - 为什么数据结构对齐对性能很重要?
有人可以给我一个简短而合理的解释,解释为什么编译器会向数据结构添加填充以对齐其成员吗?我知道这样做是为了让 CPU 可以更有效地访问数据,但我不明白为什么会这样。
如果这只是 CPU 相关的,为什么在 Linux 中对齐双 4 字节而在 Windows 中对齐 8 字节?