Skip to content

Instantly share code, notes, and snippets.

@Vengarioth
Last active February 4, 2024 06:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vengarioth/978e80892b6300b3669b to your computer and use it in GitHub Desktop.
Save Vengarioth/978e80892b6300b3669b to your computer and use it in GitHub Desktop.
Parallel for Unity3d
/// <summary>
/// Unity Parallelism Helper
/// </summary>
public static class Parallel
{
/// <summary>
/// Executes a for loop in which iterations may run in parallel.
/// </summary>
/// <param name="iterations"></param>
/// <param name="function"></param>
public static void For(int iterations, Action<int> function)
{
int iterationsPassed = 0;
ManualResetEvent resetEvent = new ManualResetEvent(false);
for (int i = 0; i < iterations; i++)
{
ThreadPool.QueueUserWorkItem((state) =>
{
int currentIteration = (int)state;
try
{
function(currentIteration);
}
catch (Exception e)
{
Debug.LogException(e);
}
if (Interlocked.Increment(ref iterationsPassed) == iterations)
resetEvent.Set();
}, i);
}
resetEvent.WaitOne();
}
/// <summary>
/// Executes a foreach loop in which iterations may run in parallel.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="function"></param>
public static void ForEach<T>(IEnumerable<T> collection, Action<T> function)
{
int iterations = 0;
int iterationsPassed = 0;
ManualResetEvent resetEvent = new ManualResetEvent(false);
foreach(var item in collection)
{
Interlocked.Increment(ref iterations);
ThreadPool.QueueUserWorkItem((state) =>
{
T subject = (T)state;
try
{
function(subject);
}
catch (Exception e)
{
Debug.LogException(e);
}
if (Interlocked.Increment(ref iterationsPassed) == iterations)
resetEvent.Set();
}, item);
}
resetEvent.WaitOne();
}
}
/// <summary>
/// Internal Debug Wrapper
/// use this instead of UnityEngine.Debug
/// </summary>
static class Debug
{
public static void Log(object message)
{
#if TEST
System.Diagnostics.Debug.WriteLine(message);
#else
UnityEngine.Debug.Log(message);
#endif
}
public static void LogException(Exception e)
{
#if TEST
System.Diagnostics.Debug.WriteLine(e.Message);
#else
UnityEngine.Debug.LogException(e);
#endif
}
@joergzdarsky
Copy link

Would you mind providing an example how you'd use your Parallel implementation in case you want to replace you sequential-for which could be for example:
for (int i = 0; i < gameObjects.Length; i++)
{
gameObjects[i].transform.localPosition += Physics.referenceFrameVelocity * Time.deltaTime;
}

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment