Многоядерный в Windows: куда идти после завершения всех потоков? - PullRequest
0 голосов
/ 28 февраля 2019

Я пишу код в NASM (64 бит) в Windows для запуска четырех одновременных потоков (каждый из которых назначен отдельному ядру) на четырехъядерном компьютере с Windows x86-64.Ниже приведен мой код реализации потока.Каждый поток вызывает одну и ту же программу.

Код показан ниже в точной последовательности, в которой он указан в исходном файле (без раздела .data и некоторого сокращенного кода).Каждый поток (ядро) выполняет Test_Function в большом массиве.Первое ядро ​​начинается с нуля элемента данных, второе ядро ​​начинается с 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
...