gpt4 book ai didi

c# - 在并行循环之间保留 ThreadLocal 是好还是坏?

转载 作者:太空宇宙 更新时间:2023-11-03 12:37:33 27 4
gpt4 key购买 nike

我正在尝试将 ThreadLocal 用于并行随机生成器。我的测试代码是这样的:

class Program
{
static void Main()
{
using (MyClass myClass = new MyClass())
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine("\nPass {0}: ", i + 1);
myClass.Execute();
}

Console.WriteLine("\nRandom Generators used: {0}", myClass.ListRNG.Count);
}

Console.WriteLine("\nPress any key...");
Console.ReadKey();
}
}

sealed class MyClass : IDisposable
{
ThreadLocal<RandomGenerator> threadRNG = new ThreadLocal<RandomGenerator>(() =>
new RandomGenerator(), true);

public IList<RandomGenerator> ListRNG { get { return threadRNG.Values; } }

public void Execute()
{
Action<int> action = (i) =>
{
bool repeat = threadRNG.IsValueCreated;
List<int> ints = new List<int>();
int length = threadRNG.Value.Next(10);
for (int j = 0; j < length; j++)
ints.Add(threadRNG.Value.NextInt(100));
Console.WriteLine("Action {0}. ThreadId {1}{2}. Randoms({3}): {4}",
i + 1, Thread.CurrentThread.ManagedThreadId,
repeat ? " (repeat)" : "", length, string.Join(", ", ints));
};

Parallel.For(0, 10, action);
}

public void Dispose()
{
threadRNG.Dispose();
}
}

class RandomGenerator : Random
{
public RandomGenerator() : base(Guid.NewGuid().GetHashCode())
{
}

public int NextInt(int maxValue)
{
return base.NextDouble() >= .5 ? base.Next(maxValue) : -base.Next(maxValue);
}
}

在并行循环的多次执行之间保留 ThreadLocal 是好还是坏?恐怕可能会累积未使用的 RandomGenerator 实例。尤其是当我有数千次处决时。

更新:我用另一个 ThreadLocal 构造函数尝试了另一个版本的测试,允许访问所有值(我已经更改了上面的代码)。

我还尝试了 100 000 次执行 myClass.Execute(),发现只创建了 17 个 RandomGenerator 实例。所以我认为(我希望)采用这种方法一切正常。

最佳答案

如果您不要求列出所有值,则每个线程的值都以线程为根。因此,如果线程死了,它们就不会保持它们的值(value)。您的代码没问题。

如果使用 [ThreadStatic] static RandomGenerator rng;,它会变得更加简单。

请注意,线程本地访问有点慢。如果让每个线程尽可能少地拉动 RNG 并保持一段时间(在架构上尽可能长),你可能会更好。

另外,.NET RNG 确实很慢而且质量很差。考虑使用 XorShift 和变体。

关于c# - 在并行循环之间保留 ThreadLocal 是好还是坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40326983/

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