2013-02-24 49 views
1

我一直在嘗試使用線程優化排序算法(快速排序)。我知道它在std :: sort()實現中已經相當不錯了,但我試圖通過對計算機進行優化來打敗它,並且同時瞭解線程。如何使用具有遞歸模板函數的線程

所以,我的問題是,我如何使用線程與我的遞歸快速排序功能?

這裏的功能(與不重要而最質疑的東西刪除):

template <typename T> 
void quicksort(T arr[], const int &size, const int &beginning, const int &end) 
{ 
    // Algorithm here 
    thread t1(quicksort, arr, size, beginning, slow - 1); 
    thread t2(quicksort, arr, size, slow + 1, end); 
} 

如果我錯了,你最終需要更多的代碼,讓我知道,我會更新它。

我使用Visual Studio 2012,以及截至目前,該錯誤狀態:

error C2661: 'std::thread::thread' : no overloaded function takes 5 arguments 

我也打過電話REF(ARR)等對每個參數的,但我得到了同樣的錯誤。

編輯: 由@mfontanini嘗試解決方法後,我可以沒有錯誤編譯,但上運行,我得到:

Debug Error! 

Program: ...sktop\VisualStudio\Projects\SpeedTester\Debug\SpeedTester.exe 

R6010 
- abort() has been called 


(Press Retry to debug the application) 

重複了一個又一遍。最終,它與代碼退出3.

回答

0

你的主要問題可能是你需要join()thread(s)你產卵。如果線程對象在沒有事先調用join()detach()的情況下被破壞,則實現將調用std::terminate()

你不想要detach(),因爲你需要知道所有的部分排序都是爲了完成整個排序而完成的,所以join ing是正確的。

此外,還有一些事情,你可以改善:

  • 你不應該被引用傳遞左右int秒。按值傳遞對於簡單標量類型更爲有效,並且引用來自其他線程的局部變量通常不是一個好主意(除非您有充足的理由和協議)
  • 您開始的線程太多了。分區之後,您需要兩個線程來處理這兩個子類,但是您有三個線程:當前線程也會繼續運行,因此您應該只創建一個新線程,並在當前線程中執行另一個子線程。 (join()完成後的其他部分。)
  • 當分區變小時,您不應該繼續創建新線程。爲快速排序設置截止大小通常是一個好主意,並且對於較小的大小使用非遞歸(如插入排序),因爲遞歸開銷高於算法複雜性優勢。類似的截斷對於併發排序更爲重要:線程的開銷遠遠高於簡單的遞歸調用,並且小分區(以及附近)的線程將開始頻繁地觸發相同的緩存行,從而減慢速度更。
  • 創建無限制線程通常不是一個好主意。這最終會遇到平臺限制。您可能希望限制要使用的線程數(使用原子計數器)或使用諸如std::async之類的默認啓動策略,以避免啓動比平臺可處理的更多線程。
+0

謝謝!這與@mfontanini得到我的代碼運行。並感謝您的額外信息!我一定記住它。 – Leonhart231 2013-02-24 18:36:55

2

你需要明確指出哪些是T模板參數:

thread t1(&quicksort<T>, arr, size, beginning, slow - 1); 

否則編譯器看到的,你指的是一個函數模板,而不是具體哪專業化;它無法從無處推導出T