我必須對 DigitalMicrographs 的 DM 腳本語言中的資料執行 CPU 密集型分析。我注意到在處理程序中只有一個 CPU 核心最大化。有沒有辦法通過 DM 腳本中的多執行緒來獲得更好的性能?簡單的例子將不勝感激。
uj5u.com熱心網友回復:
多執行緒在 DM 腳本中當然是可能的,它記錄在 F1 幫助中:

能否實作速度提升取決于各種因素,最重要的是各個執行緒是否需要訪問相同的資源(例如相同的資料,或者某些只能通過主執行緒訪問的 GMS 資源 - fe the UI )。
此外,當您在影像運算式上使用命令時,許多資料處理在內部已經是多執行緒的。通過以不需要腳本語言中的 for 回圈而是使用影像運算式的方式重新表述分析處理,您可能會獲得更多的加速。
最后,多執行緒處理是引入錯誤和意外行為的好方法,這些行為可能真的很難除錯。如果您在學習內容時遇到這些問題,請不要感到沮喪。
也就是說,下面的示例演示(至少在我的機器上)通過在多個并行后臺執行緒上“分塊”一些資料分析來提高速度。
// Example showing the explicit use of multi-threading in DM scripting
class CMultiThreadtest
{
image data, keep
number sx,sy,sz
number nChunks, chunksize, lastChunk, doneChunk
object SetData(object self, image img, number nChunks_)
{
if ( img.imagegetNumdimensions() != 3 ) throw( "only 3D data for testing please")
img.ImageGetDimensionSizes(sx,sy,sz)
nChunks = nChunks_
if ( sz % nChunks != 0 ) Throw( "Z-size needs to be integer multiple of nChunks for this test.")
chunksize = sz / nChunks
data:=img
keep = data
return self
}
void CompareResult(object self){
image dif := keep*2-data
number ok = 0==sum(dif)
Result("\n\t Result is " (ok?"correct":"wrong"))
}
void RunOnData(object self){
// For extra-caution of thread safety, the two lines below shoud be guarded with critical sections
// but given the near-atomic nature of the call, this is omitted here.
number chunkIndex = lastChunk
lastChunk
image work := data.slice3(0,0,chunkIndex*chunksize, 0,sx,1, 1,sy,1, 2,chunksize,1)
number startp = GetHighresTickCount()
for( number z=0;z<chunksize;z )
for( number y=0;y<sy;y )
for( number x=0;x<sx;x ){
work[x,y,z] *= 2
}
number endp = GetHighresTickCount()
Result("\n\t\t Process (chunk " chunkIndex ") done with " sx*sy*chunksize " steps in " (endp-startp)/GetHighResTicksPerSecond())
// For extra-caution of thread safety, the line below shoud be guarded with critical sections
// but given the near-atomic nature of the call, this is omitted here.
doneChunk
}
void RunWithSubsets(object self, image src, number nChunks_, number inbackground){
self.SetData(src, nChunks_)
lastChunk = 0
doneChunk = 0
Result("\n.....\n Running with " nChunks " chunks of size " chunksize " on " (inbackground?" multiple background threads":" single main thread") ":")
number startp = GetHighresTickCount()
for( number i=0; i<nChunks; i ){
if ( inbackground )
self.StartThread("runondata")
else
self.RunOnData()
}
while( doneChunk != nChunks ){
if ( ShiftDown() ){
Throw("abort")
doEvents()
}
}
number endp = GetHighresTickCount()
Result("\n Total duration:" (endp-startp)/GetHighResTicksPerSecond())
self.CompareResult();
Result("\n.....")
}
};
void Test(){
image img := RealImage("test cub",4,50,50,10)
img = random()
clearresults()
object tester = Alloc(CMultiThreadtest)
tester.RunWithSubsets(img, 1, 0)
tester.RunWithSubsets(img, 1, 1)
tester.RunWithSubsets(img, 5, 0)
tester.RunWithSubsets(img, 5, 1)
}
test()
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/380140.html
