代码之家  ›  专栏  ›  技术社区  ›  RTC222

Windows中的多核:所有线程完成后要去哪里?

  •  0
  • RTC222  · 技术社区  · 7 年前

    我正在Windows中用NASM(64位)编写代码,以便在四核Windows x86-64机器上同时运行四个线程(每个线程分配给一个单独的核心)。下面是我的线程实例化代码。每个线程调用相同的程序。

    代码如下所示,其显示顺序与源文件中的显示顺序完全相同(没有.data部分,有些代码缩写)。每个线程(核心)在一个大数组中执行Test_函数。第一个核心从数据元素0开始,第二个核心从1开始,第三个核心从2开始,第四个核心从3开始,每个核心递增4(例如,0、4、8、12)。完成后,Test_函数在标签_899处退出。它们将结果写入使用malloc创建的共享数组中的相应位置。

    我的问题是:在标签_899上完成所有线程后,我要去哪里?然后线程是否返回到执行清理的ThreadStart的最后一行(jl label_0之后)?Test_函数随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
    
    0 回复  |  直到 7 年前