2012-11-07 73 views
1

我剛剛發現gcc的OpenMP實現(libgomp)不調用pthread_exit()。 我需要使用perfsuite(用於剖析)。讓GCC在轉換OpenMP並行代碼時調用pthread_exit

有沒有什麼辦法可以告訴GCC在將OpenMP代碼轉換爲pthread代碼的同時,在OpenMP的並行部分的末尾包含pthread_exit()?

我使用的是GCC 4.7.0和Perfsuite 1.1.1。

回答

3

libgomp實現線程池。創建完成後,池中的線程將保持空閒狀態,直到它成爲線程組的成員。團隊完成工作後,線程會進入空閒循環,直到再次發出信號。游泳池按需增長,但從不縮水。線程僅在程序結束時發出信號退出。

您可以閱讀在4.7.x分支here中實現線程池和團隊的libgomp代碼。

池線程以這種方式終止:libgomp通過名稱team_destructor()註冊析構函數。只要main()函數返回,exit(3)被調用或libgomp庫通過調用dlclose(3)(如果先前加載了dlopen(3))而被卸載,就會調用它。析構函數刪除一個pthreads鍵的名稱爲gomp_thread_destructor,該名稱具有由刪除觸發的相關析構函數gomp_free_thread()gomp_free_thread()使池中的所有線程執行gomp_free_pool_helper()作爲他們的下一個任務。 gomp_free_pool_helper()調用pthread_exit(3),因此池中的所有線程都不存在。

這裏是一個不錯的ASCII畫面相同的過程:

main() returns, exit() called or library unloaded 
    | 
    | 
team_destructor() deletes gomp_thread_destructor 
    | 
    | 
gomp_free_thread() called by pthreads on gomp_thread_destructor deletion 
    | 
    +-------------------------+---------------------------+ 
    |       |       | 
gomp_free_pool_helper() gomp_free_pool_helper() ... gomp_free_pool_helper() 
installed as next task installed as next task  installed as next task 
    |       |       | 
    |       |       | 
pthread_exit(NULL)  pthread_exit(NULL)  ... pthread_exit(NULL) 

注意,這只是在程序執行結束時發生一次,而不是在每個區域parallel的結束。

+0

嗨Hristo,謝謝你的回答。據我瞭解,當程序退出,即線程獲取信號時,它不會調用pthread_exit()。似乎我需要更改此文件(team.c)的代碼來執行此操作。是對的嗎?如果是這樣,有沒有簡單的方法來做到這一點? – Rakib

+1

線程在'gomp_thread_start()'的後半部分運行循環,只要它們具有在對接屏障後執行的函數,否則它們將退出循環並簡單地返回。當線程調用'pthread_exit'時有一種情況,'libgomp'在運行時用'dlopen(3)'加載時就是這種情況。有一個關鍵的'gomp_thread_destructor'與一個關聯的析構函數'gomp_free_thread()'和一個名爲'team_destructor()'的文件析構函數被註冊。當你把庫關閉時,文件析構函數被調用,並且它使得所有的團隊線程都調用pthread_exit。 –

+1

對不起,我的錯誤 - 函數'__attribute __((析構函數))'也在'main()'返回後調用。這意味着池線程肯定會到達他們稱之爲「pthread_exit」的地方,但不會在'main'函數返回之前。不幸的是,'libgomp' API對用戶不可用,並且您不能在'main()'結束之前調用池析構函數。 –

相關問題