Posix memalign在Broadwell上失败,但在Skylake上失败

问题描述

以下代码使用Posix Memalign为每个内核分配四个缓冲区,每个缓冲区128个字节。它在Skylake上成功,但在broadwell(早期)上失败,并显示以下消息:

onEmailChange(e) {
  this.props.setEmailText(e.target.value);
}

根据Linux手册页,在以下情况下,memalign将失败:(1)对齐参数不是2的幂,或者不是sizeof(void *)的倍数,或者(2)不足内存以满足分配请求。由于它产生分段错误,因此无法从rax获取错误号。 broadwell具有8GB的内存,因此内存不足不是问题。对齐方式是64,所以这不是问题,无论如何它在我的Skylake上都成功,因此可以正确编写。

这是相关的代码块:

posix memalign malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' Failed

它在“调用posix_memalign wrt ..plt”处失败,并显示上面显示错误消息以及分段错误消息。

这对我来说是一个难题,因为它在Skylake上成功了,而posix_memalign早于broadwell。

我组装并链接到:

sudo nasm -f elf64 -g -F矮人NWL.asm

sudo ld-共享NWL.o /opt/P01_SH/_Library/Create_Threads_in_C-NWL.o /opt/P01_SH/_Library/Timer_for_NASM.o /opt/P01_SH/_Library/POSIX_Shared_Memory.o / opt / P01_SH / _Mbrx .o /opt/P01_SH/_Library/Create_Multi_Files.o -ldl -lrt -lpthread -lm -o NWL.so

感谢您提出任何想法。

解决方法

我从kisch的注释中解决了这个问题(“断言消息似乎表明了堆损坏的情况。然后实际的错误将出现在较早的代码中,只有在您的函数尝试进行另一次分配时才检测到损坏” )。

我的NASM代码包括两个带有内存分配代码的文件。在修复之前,它是:

; Create buffers to hold POSIX shared memory: 
mov rbx,2 ; 2 output buffers per core
%include "/opt/P01_SH/_Include_Utilities/POSIX_Shared_Memory.asm"

mov r15,1 ;[Number_Of_Cores_Seq]
mov r12,4 ; number of internal_buffers needed
%include "/opt/P01_SH/_Include_Utilities/Posix_Memalign_Internal.asm"

要解决此问题,我调换了调用顺序,以便在Posix_Shared_Memory.asm之前包含Posix_Memalign_Internal.asm。

这是Posix_Memalign_Internal.asm中的代码:

mov rax,r15
mov rbx,r12 ; passed in from calling function
mul rbx
mov r14,rax
xor r13,r13

Memalign_Create_Loop:

; Allocate the buffer for the memory pointers
; # of cores times N memory pointers needed (passed in from caller)
; int posix_memalign(void **memptr,size_t alignment,size_t size);

mov rax,r15 ; number of cores
mov rbx,r12 ; number of buffers needed
 ; N ptrs per core x 8 bytes per pointer
mul rbx ; times the number of cores
mov r12,rax ; number of buffers needed x number of cores
lea rdi,[memalign_pointer]
mov rsi,64 ; alignment
mov rdx,r12
shl rdx,3
mov rdx,128 ; buffer size
sub rsp,40
call posix_memalign wrt ..plt
add rsp,40
lea r8,[internal_buffer_pointers]
lea rdi,[memalign_pointer]
mov rax,[rdi]
mov rbx,r13
shl rbx,3
mov [r8+rbx],rax
add r13,1
cmp r13,r14
jl Memalign_Create_Loop

这是Posix_Shared_Memory.asm中的代码:

mov rax,[Number_Of_Cores_Seq]
mul rbx
mov [shm_buffers_count],rax
shl rax,3
mov [shm_buffers_bytes],rax
mov r12,rax ; length of pointer buffer

; Buffer for shm pointers
mov rdi,r12
sub rsp,40
call [rel malloc wrt ..got]
mov qword [shm_buffers_ptr],rax
add rsp,40

; Buffer for shm fds
mov rdi,40
call [rel malloc wrt ..got]
mov qword [shm_fds_ptr],40

; _________
; Allocate shared memory

xor r12,r12 ; buffer # (0,8,16,24)
xor r13,r13 ; core# (0,1,2,3,...)
xor r14,r14 ; counter for shm_buffer

Get_ShmName:
lea rdi,[shm_base_name]
mov rsi,r12
mov rdx,r13
call [rel get_shm_name wrt ..got]
mov rdi,rax
push rdi ; shm_name ptr
call [rel unlink_shm wrt ..got]
pop rdi

; Create the shm buffer
mov rsi,[shm_size]
call [rel open_shm wrt ..got]
get_buffer:
mov rdi,rax
mov rax,[rdi]
get_buffer_data:
mov rbp,[shm_fds_ptr]
mov [rbp+r14],rax ; shm_fds
mov rbp,[shm_buffers_ptr]
mov rax,[rdi+8]
mov [rbp+r14],rax ; shm_ptrs
add r12,8
add r14,8
cmp r12,[shm_buffers_bytes]
jl Get_ShmName
next_core:
xor r12,r12
add r13,[Number_Of_Cores_Seq]
jl Get_ShmName

Posix_Memalign_Internal.asm使用posix_memalign创建四个每个128字节的小缓冲区。 Posix_Shared_Memory.asm创建两个4MB共享内存缓冲区。

由此得出的结论是,当在同一程序中使用posix_memalign和posix共享内存时,应在创建posix共享内存缓冲区之前调用posix_memalign。在最终的可执行文件中,它们依次出现,中间有3条指令。

我在代码块中看不到任何能解释为什么的代码,但是在这里解决了这个问题。

最后要说的是,它今天在Skylake上失败了,因此CPU系列无关紧要,如Nate Eldredge在上面的评论中所述。

感谢所有答复。