gpt4 book ai didi

c# - 模拟给出不同的结果与正常的 for 循环 Vs Parallel For

转载 作者:太空狗 更新时间:2023-10-30 00:55:57 26 4
gpt4 key购买 nike

当我尝试使用普通 for 循环(这是正确的结果)与 Parallel For 时,我对我的一个简单模拟示例的不同结果感到有点惊讶。请帮我找出可能是什么原因。我观察到并行执行与正常执行相比是如此之快。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Simulation
{
class Program
{

static void Main(string[] args)
{
ParalelSimulation(); // result is .757056
NormalSimulation(); // result is .508021 which is correct
Console.ReadLine();
}

static void ParalelSimulation()
{
DateTime startTime = DateTime.Now;

int trails = 1000000;
int numberofpeople = 23;
Random rnd = new Random();
int matches = 0;

Parallel.For(0, trails, i =>
{
var taken = new List<int>();
for (int k = 0; k < numberofpeople; k++)
{
var day = rnd.Next(1, 365);
if (taken.Contains(day))
{
matches += 1;
break;
}
taken.Add(day);
}
}
);
Console.WriteLine((Convert.ToDouble(matches) / trails).ToString());
TimeSpan ts = DateTime.Now.Subtract(startTime);
Console.WriteLine("Paralel Time Elapsed: {0} Seconds:MilliSeconds", ts.Seconds + ":" + ts.Milliseconds);
}
static void NormalSimulation()
{
DateTime startTime = DateTime.Now;

int trails = 1000000;
int numberofpeople = 23;
Random rnd = new Random();
int matches = 0;

for (int j = 0; j < trails; j++)
{
var taken = new List<int>();
for (int i = 0; i < numberofpeople; i++)
{
var day = rnd.Next(1, 365);
if (taken.Contains(day))
{
matches += 1;
break;
}
taken.Add(day);
}
}
Console.WriteLine((Convert.ToDouble(matches) / trails).ToString());
TimeSpan ts = DateTime.Now.Subtract(startTime);
Console.WriteLine(" Time Elapsed: {0} Seconds:MilliSeconds", ts.Seconds + ":" + ts.Milliseconds);
}
}

提前致谢

最佳答案

一些事情:

  1. Random 类不是线程安全的。每个工作线程都需要一个新的 Random 实例。
  2. 您正在以非线程安全的方式递增 matches 变量。您可能希望使用 Interlocked.Increment(ref matches) 来保证变量递增时的线程安全。
  3. 您的 for 循环和您的 Parallel::For 执行的次数不完全相同,因为您在 for 循环中执行了一个 <= 并且 Parallel::For 的第二个参数独占,所以您在这种情况下,需要将路径加 1 以使它们相等。

试试这个:

static void ParalelSimulationNEW()
{
DateTime startTime = DateTime.Now;

int trails = 1000000;
int numberofpeople = 23;
int matches = 0;

Parallel.For(0, trails + 1, _ =>
{
Random rnd = new Random();

var taken = new List<int>();
for(int k = 0; k < numberofpeople; k++)
{
var day = rnd.Next(1, 365);
if(taken.Contains(day))
{
Interlocked.Increment(ref matches);
break;
}
taken.Add(day);
}
});
Console.WriteLine((Convert.ToDouble(matches) / trails).ToString());
TimeSpan ts = DateTime.Now.Subtract(startTime);
Console.WriteLine("Paralel Time Elapsed: {0} Seconds:MilliSeconds", ts.Seconds + ":" + ts.Milliseconds);
}

关于c# - 模拟给出不同的结果与正常的 for 循环 Vs Parallel For,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8944915/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com