gpt4 book ai didi

c# - 将 .NET 4 线程转换为 .NET 2

转载 作者:太空狗 更新时间:2023-10-29 23:46:01 24 4
gpt4 key购买 nike

我正在使用其他人的 .NET 4 开源平滑粒子流体动力学代码,我正在尝试将其转换为 Unity 项目,您只能指望它达到 .NET 2 标准。不幸的是,代码使用了 Parallels 类(这太棒了!),但他使用了一个更晦涩的重载。有谁能找到一种在 .NET 2 中实现相同目标而又不会对性能造成巨大影响的好方法吗?

    Parallel.For(
0,
_numActiveParticles,
() => new Vector2[MAX_PARTICLES],
(i, state, accumulatedDelta) => calculateForce(_activeParticles[i], accumulatedDelta),
(accumulatedDelta) =>
{
lock (_calculateForcesLock)
{
for (int i = _numActiveParticles - 1; i >= 0; i--)
{
int index = _activeParticles[i];
_delta[index] += accumulatedDelta[index] / MULTIPLIER;
}
}
}
);

认为这就是代码的作用(非线程):

    for (int i = 0; i < _numActiveParticles; i++)
{
Vector2[] temp = new Vector2[MAX_PARTICLES];
temp = calculateForce(_activeParticles[i], temp);


for (int k = _numActiveParticles - 1; k >= 0; k--)
{
int index = _activeParticles[k];
_delta[index] += temp[index] / MULTIPLIER;
}
}

最佳答案

您的第二个代码不正确。我认为正确的代码是这样的:

var accumulatedDelta= new Vector2[MAX_PARTICLES];

for(int i = 0; i < _numActiveParticles; ++i)
{
accumulatedDelta = calculateForce(_activeParticles[i], accumulatedDelta);
}

for (int i = _numActiveParticles - 1; i >= 0; i--)
{
int index = _activeParticles[i];
_delta[index] += accumulatedDelta[index] / MULTIPLIER;
}

我不知道 .net2 有什么,没有什么。但是您可以自己模拟 Parallel.For

Parallel.For 重载的解释是这样的:

第一个参数:循环起始索引

第二个参数:循环结束索引

第三个参数:将创建任务本地数据的委托(delegate)。对于 Parallel.For 使用的每个线程(任务),将调用此委托(delegate)并返回 localInit 数据。

第四个参数:作为for主体的委托(delegate)。在 body delegate 的第一次执行中,该委托(delegate)将检索由 previuse delegate (localInit) 创建的数据。在每个后续循环中,主体委托(delegate)可以更改 localInit,然后将其返回给下一个主体执行。在主体委托(delegate)的最后一次执行中,localInit 数据将传递给最后一个委托(delegate)。

最后一个参数:每个任务将调用的另一个委托(delegate),当任务完成它的工作时。 localInit 将传递给此委托(delegate)。因为这个委托(delegate)可以被多个任务调用并发,所以你必须保护你的共享数据。

编辑:

ParallelFor 的一个版本可以是这样的:

public static void ParallerFor<TLocal>(int startIndex, int endIndex, Func<TLocal> initData, Func<int, TLocal, TLocal> body, Action<TLocal> finalizer)
{
int numThreads = Environment.ProcessorCount;
int chunkOffset = ((endIndex - startIndex) / numThreads) + 1;

Task[] tasks = new Task[numThreads];

Enumerable.Range(0, numThreads).ToList().ForEach(x =>
{
int start = x * chunkOffset;
int end = ((x + 1) * chunkOffset);
end = end > endIndex ? endIndex : end;

tasks[x] = Task.Factory.StartNew(() =>
{
TLocal init = initData();

for(int i = start; i < end; ++i)
{
init = body(i, init);
}

finalizer(init);
});
});

Task.WhenAll(tasks).Wait();
}

关于c# - 将 .NET 4 线程转换为 .NET 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20652011/

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