我有以下代码(控制台应用程序的“Program.cs”的完整内容).
‘countUp’直到’countUp4’的单线程执行需要13秒,多线程执行21秒..
‘countUp’直到’countUp4’的单线程执行需要13秒,多线程执行21秒..
我有Intel Core i5-2400 @ 3.10 GHz,8 GB Ram,Windows 7 64位.那么为什么mutli线程执行比单线程执行慢?
多线程只是用于阻止简单的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()); } } }
解决方法
这是一个你可能看不到来的原因:
false sharing因为这4个内存都并排在内存中.
更新 – 前几年的MSDN mags现在只能作为.chm文件使用 – 所以你必须抓住‘October 2008’ edition of the MSDN Mag from here,下载后,您必须记住在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();
我使这些数组真的比他们需要的更大,希望它会证明它更好:)