它怎麼能這樣做?我認爲這只是一個核心!
您看到所有正在使用的核心並不意味着您的代碼執行是並行的。我們可以從實現中看到它是連續的,但是我們不知道在每個週期中,我們的單個線程將由操作系統調度到哪個CPU。
當您在一個線程內執行一個方法時,操作系統會根據它管理的優先級隊列決定它將得到的CPU時間片數以及時間片的數量。
爲了看到你的算法可以在不同的內核上運行,我們可以詢問操作系統在哪個邏輯核心上執行我們的線程。我爲Windows準備了一個小型實現,它具有一個名爲GetCurrentProcessorNumber()
的原生WinAPI方法,該方法返回我們正在執行的處理器編號。我們將使用JNA的例子:
build.sbt:
"net.java.dev.jna" % "jna" % "4.4.0"
Java實現:
import com.sun.jna.Library;
import com.sun.jna.Native;
public class ProcessorNumberNative {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary("Kernel32.dll",
CLibrary.class);
Integer GetCurrentProcessorNumber();
}
}
現在,讓我們每個在你的遞歸步驟添加println
:
def reduceRes[A](t: Tree[A], f: (A, A) => A): TreeRes[A] = t match {
case Leaf(v) =>
println(s"Logical Processor Number: ${ProcessorNumberNative.CLibrary.INSTANCE.GetCurrentProcessorNumber()}")
LeafRes(v)
case Node(l, r) =>
println(s"Logical Processor Number: ${ProcessorNumberNative.CLibrary.INSTANCE.GetCurrentProcessorNumber()}")
val (tL, tR) = (reduceRes(l, f), reduceRes(r, f))
NodeRes(tL, f(tL.res, tR.res), tR)
}
現在讓我們創建一個樹並執行:
def main(args: Array[String]): Unit = {
val tree = Node(Leaf(1),
Node(Leaf(2),
Node(Node(Leaf(24), Leaf(30)),
Node(Leaf(3), Node(Leaf(10), Leaf(52))))))
reduceRes(tree, (a: Int, b: Int) => a + b)
}
,讓這個兩個不同的運行(我運行4個邏輯核心計算機):
第一:
Logical Processor Number: 1
Logical Processor Number: 3
Logical Processor Number: 3
Logical Processor Number: 3
Logical Processor Number: 0
Logical Processor Number: 0
Logical Processor Number: 0
Logical Processor Number: 3
Logical Processor Number: 0
Logical Processor Number: 0
Logical Processor Number: 0
Logical Processor Number: 0
Logical Processor Number: 0
二:
Logical Processor Number: 1
Logical Processor Number: 3
Logical Processor Number: 1
Logical Processor Number: 1
Logical Processor Number: 1
Logical Processor Number: 1
Logical Processor Number: 1
Logical Processor Number: 1
Logical Processor Number: 3
Logical Processor Number: 3
Logical Processor Number: 3
Logical Processor Number: 3
Logical Processor Number: 3
在每執行,你會發現正在執行的線程在3個不同的內核0,1和3上得到了一個執行片,而我們仍然在一個單線程中運行vironment。這表明,儘管算法的計算絕對是順序的,但這並不意味着您不會看到所有核心在使用。
你確定使用多個核心嗎?真的看起來沒有機會在這個來源的任何併發 - 沒有平行的集合,沒有期貨... – Suma
你可能會發佈一個更完整的例子,包括你如何創建樹實例並運行'reduceRes'? – Suma
我與使用此代碼的katie具有相同的問題:https://pastebin.com/dNFMxN7F雖然沒有機會使用所有內核 – rubiktubik