我有一个关于 Windows 和 Linux 上的线程(或纤程)的一般性问题,使用任何编程语言:
是否有可能让“第二个线程待命”并让它迅速投入行动并在几毫秒内帮助完成一项小任务,而不会被抢先?我应该补充一点,我希望没有互斥锁和自旋锁的清晰代码。
为了证明传统的线程池不适用于小型任务,请考虑 C# 中的矩阵求逆问题。我正在使用 Ivan Kuckir 的矩阵类。我复制他的 Invert 函数并将其称为 InvertParallel,如下所示:
public Matrix InvertParallel() // modified from Ivan's Invert(), see link above
{
if (L == null) MakeLU();
Matrix inv = new Matrix(rows, cols);
Parallel.ForEach<int>(Enumerable.Range(0, rows), rowID =>
{
Matrix Ei = Matrix.ZeroMatrix(rows, 1);
Ei[rowID, 0] = 1;
Matrix col = SolveWith(Ei);
inv.SetCol(col, rowID);
});
return inv;
}
然后我调用 Invert 和 Invert_Parallel 函数并测量它所花费的时间:
static void Main()
{
Stopwatch sw = new Stopwatch(); sw.Start();
Matrix A = Matrix.IdentityMatrix(50, 50);
Matrix I1 = A.Invert();
long elapsed1 = sw.ElapsedMilliseconds;
Matrix I2 = A.InvertParallel();
long elapsed2 = sw.ElapsedMilliseconds - elapsed1;
Console.WriteLine("Matrix size=" + A.rows + ", Invert=" + elapsed1 + "ms, Invert_Parallel=" + elapsed2 + "ms");
}
相当明显的结果表明,对于小型任务(矩阵大小 50),从线程池启动任务比运行单线程慢:
Matrix size=50, Invert= 5ms, InvertParallel=21ms
Matrix size=100, Invert= 19ms, InvertParallel=24ms
Matrix size=200, Invert=137ms, InvertParallel=44ms
(道歉 - 我必须从下面的注释中删除所有链接,因为我是新海报)
PS 可能相关的 S/O 文章:《如何同时启动两个线程》、《Linux - 线程和进程调度优先级》
PS 是的,我知道有一个更聪明的算法来计算逆,它的比例为 O(N^2.376)。
PPS 我不熟悉用户模式调度(Windows 上的 UMS)用户模式调度(Windows 上的“UMS”),有帮助吗?