我正在Windows的NASM(64位)中编写代码,以在四核Windows x86-64计算机上运行四个同时线程(每个线程都分配给一个单独的内核)。下面是我的线程实例化代码。每个线程调用相同的程序。
下面以完全按照顺序显示在源文件中的代码显示了代码(没有.data节,并且有些代码缩写)。每个线程(核心)在大型数组上执行Test_Function。第一个核心从数据元素0开始,第二个核心从1开始,第三个核心从2开始,第四个核心从3开始,每个核心递增四(例如0、4、8、12)。完成后,Test_Function在label_899退出。他们将结果写入使用malloc创建的共享数组中的相应位置。
我的问题是:在label_899中所有线程完成之后我应该去哪里?线程然后返回到执行清理的ThreadStart的最后一行(在jl label_0之后)吗? Test_Function以ret退出,因此我假定将控制权返回到线程实例化部分(ThreadStart)。
不幸的是,我所阅读的所有信息都集中在单个线程的创建上。一些资源讨论了运行时的线程同步,但是我发现与所有线程完成后发生的情况没有直接关系。
感谢您的帮助。我会发布一个完整的示例,但是我还不知道如何完成它,这是我的问题。
ThreadStart:
mov rbp,rsp ; preserve caller's stack frame
mov rdi,ThreadInfo ; two element array
sub rsp,32 ; Shadow space
label_0:
mov rax,StartByte
mov [rdi],rax ; 0, 8, 16, or 24
mov rax,[JumpCount]
mov [rdi+8],rax ; number of cores (4 in this example)
push 0 ; Creation flags, start immediately (may want to delay until all created)
push 0 ; ThreadID
mov rcx,0 ; lpThreadAttributes (Security Attributes)
mov rdx,0 ; dwStackSize
mov r8,Test_Function ; lpStartAddress (function pointer)
mov r9,rdi ; lpParameter
call CreateThread
mov rax,8
add [StartByte],rax
mov rax,[TreadCount]
add rax,1
mov [TreadCount],rax
cmp rax,4
jl label_0
[ Code to do cleanup if needed after the four threads finish ]
mov rsp,rbp
jmp final_out
;______
Test_Function:
xor rcx,rcx
mov [loop_counter_401],rcx
label_401:
lea rdi,[rel numbers_ptr]
mov rbp,qword [rdi] ; Pointer
mov rcx,[loop_counter_401]
mov rax,[numbers_length]
cmp rcx,rax
jge label_899
movsd xmm0,qword[rbp+rcx]
movsd [num_float],xmm0
add rcx,32 ;8 -- add 32 for four loops, not 8
mov [loop_counter_401],rcx
[ MORE CODE]
jmp label_401
label_899:
ret
;______
final_out:
mov rdi,Return_Pointer_Array
mov rax,r15
mov [rdi+0],rax
mov rax,r14
mov [rdi+8],rax
mov rax,rdi
ret
更新030119
以下是创建线程的代码。之前我虽然在CreateThread上失败了,但是没有失败。由于我调用的代码有问题,现在失败了,现在我正在调试它。我将回发我的结果。失败的原因可能在于我如何编写WaitForMultipleObjects的代码。
显示的是线程实例化代码,而不是线程调用的代码。
mov rdi,ThreadInfo
mov rax,StartByte
mov [rdi+8],rax ; 0, 8, 16, or 24
; _____
; Create Threads
mov rcx,0 ; lpThreadAttributes (Security Attributes)
mov rdx,0 ; dwStackSize
mov r8,Test_Function ; lpStartAddress (function pointer)
mov rax,rdi
mov r9,rax ; lpParameter (array of data passed to each core)
mov rax,0
mov [rsp+40],rax ; use default creation flags
mov rax,[ThreadCount]
mov [rsp+32],rax ; ThreadID
call CreateThread
; Move the handle into ThreadHandles array (returned in rax)
mov rdi,ThreadHandles
mov rcx,[StartByte]
mov [rdi+rcx],rax
mov rax,8
add [StartByte],rax
mov rax,[ThreadCount]
add rax,1
mov [ThreadCount],rax
cmp rax,4
jl label_0
; _____
; Wait
mov rcx,rax ; number of handles
mov rdx,ThreadHandles ; pointer to handles array
mov r8,1 ; wait for all threads to complete
mov r9,1000 ; milliseconds to wait
call WaitForMultipleObjects
; _____
;[ Code to do cleanup if needed after the four threads finish ]
mov rsp,rbp
jmp label_900