我有以下代码(控制台应用程序“Program.cs”的完整内容)。
单线程执行“countUp”到“countUp4”需要 13 秒,多线程执行需要 21 秒。
我有 Intel Core i5-2400 @ 3.10 GHz、8 GB RAM、Windows 7 64 位。那么为什么多线程执行速度比单线程执行速度慢呢?
多线程仅对不阻塞简单 C# 应用程序的主例程有用吗?多线程何时在执行速度上给我带来优势?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static int counter = 0;
static int counter2 = 0;
static int counter3 = 0;
static int counter4 = 0;
static void Main(string[] args)
{
Console.WriteLine("Without multithreading:");
Console.WriteLine("Start:" + DateTime.Now.ToString());
countUp();
countUp2();
countUp3();
countUp4();
Console.WriteLine("");
Console.WriteLine("With multithreading:");
Console.WriteLine("Start:" + DateTime.Now.ToString());
Thread thread1 = new Thread(new ThreadStart(countUp));
thread1.Start();
Thread thread2 = new Thread(new ThreadStart(countUp2));
thread2.Start();
Thread thread3 = new Thread(new ThreadStart(countUp3));
thread3.Start();
Thread thread4 = new Thread(new ThreadStart(countUp4));
thread4.Start();
Console.Read();
}
static void countUp()
{
for (double i = 0; i < 1000000000; i++)
{
counter++;
}
Console.WriteLine(counter.ToString());
Console.WriteLine(DateTime.Now.ToString());
}
static void countUp2()
{
for (double i = 0; i < 1000000000; i++)
{
counter2++;
}
Console.WriteLine(counter2.ToString());
Console.WriteLine(DateTime.Now.ToString());
}
static void countUp3()
{
for (double i = 0; i < 1000000000; i++)
{
counter3++;
}
Console.WriteLine(counter3.ToString());
Console.WriteLine(DateTime.Now.ToString());
}
static void countUp4()
{
for (double i = 0; i < 1000000000; i++)
{
counter4++;
}
Console.WriteLine(counter4.ToString());
Console.WriteLine(DateTime.Now.ToString());
}
}
}
这是一个你可能看不到的原因:虚假分享因为这 4 个整数在内存中都是并排的。
更新 - 前几年的 MSDN 杂志仅作为.chm
现在文件 - 所以你必须抓住MSDN Mag 的“2008 年 10 月”版来自此处并且,下载后,您必须记住在打开文件之前,在 Windows 资源管理器(其他操作系统也可用!)的文件属性对话框中右键单击并“取消阻止”该文件。您正在寻找 Stephen Toub、Igor Ostrovsky 和 Huseyin Yildiz 撰写的名为“.Net Matters”的专栏
这篇文章(阅读全文 - 太精彩了)展示了内存中并排的值在更新时如何最终导致阻塞,因为它们都位于同一缓存行上。这是非常低级的阻止,您无法从 .Net 代码中禁用它。但是,您可以强制将数据间隔得更远,以便保证或至少增加每个值位于不同缓存行上的可能性。
本文使用数组 - 但它可能会影响您。
为了遵循下面的建议,您可以通过稍微更改代码来证明/反驳这一点:
class Program
{
class CounterHolder {
private int[] fakeInts = new int[1024];
public int Value = 0;
}
static CounterHolder counter1 = new CounterHolder();
static CounterHolder counter2 = new CounterHolder();
static CounterHolder counter3 = new CounterHolder();
static CounterHolder counter4 = new CounterHolder();
然后修改你的线程函数来操作公共字段Value
在每个柜台持有人上。
我已经将这些数组做得比实际需要的大得多,希望能更好地证明这一点:)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)