Hi,
I'm extremely interested in a portable subset version of BEPU Physics. What's the likely hood of this happening soon? Would it be possible for me to port it over myself or is there a lot to change? I think the biggest thing would be the lack of threads. Perhaps we could work together to get this done?
Thanks,
-Toaster
Portable Subset
Portable Subset
Last edited by toaster on Sat Mar 21, 2015 10:28 pm, edited 1 time in total.
Re: Portable Subset
I've downloaded the source code and modified it to work inside of a PCL. It wasn't too difficult. However I do have some questions. Is there a reason you didn't use .net's hashset? Because of .net 2.0 I suppose? Also there was this line:
loopFinished.Close();
Close does not exist for an AutoResetEvent I changed this to Dispose() instead. Is this acceptable? I tried looking online, but I couldn't find much.
Finally all the threads were changed to tasks and the Thread.Sleep was changed to Task.Delay inside of the spinlock class. The Thread.SpinWait was also changed to a Task.Delay, although if I read right between the differences in spinwait and sleep that is probably not the best thing to use, however I believe it should work correct?
I might try to port the samples over to monogame or maybe Paradox3D(which only uses PCL). That way I can test to see if it's working or not.
Thanks,
-Toaster
loopFinished.Close();
Close does not exist for an AutoResetEvent I changed this to Dispose() instead. Is this acceptable? I tried looking online, but I couldn't find much.
Finally all the threads were changed to tasks and the Thread.Sleep was changed to Task.Delay inside of the spinlock class. The Thread.SpinWait was also changed to a Task.Delay, although if I read right between the differences in spinwait and sleep that is probably not the best thing to use, however I believe it should work correct?
I might try to port the samples over to monogame or maybe Paradox3D(which only uses PCL). That way I can test to see if it's working or not.
Thanks,
-Toaster
Re: Portable Subset
.NET's HashSet is used in a few places, unless you're talking about an older version that had a conditional "HashSet" wrapper around Dictionary due to API holes on the Xbox360's compact framework.Is there a reason you didn't use .net's hashset? Because of .net 2.0 I suppose?
If you're referring to the QuickSet, then it's mostly for minor performance reasons:
1) It offers greater reusability of underlying arrays. Resizing doesn't generate garbage, and a QuickSet<int> and a QuickList<int> can pull from the same pool of arrays.
2) It avoids GC involvement at the instance level by being a value type (while biting the bullet on all the complications that entails).
3) QuickSet's implementation is focused on enumeration speed. The elements are stored in a contiguous array, so enumeration does not require any memory hopping. Adds/removes are still competitive with the regular HashSet on most types.
4) The Quick collections are very raw and expose their guts. For example, the elements array can be accessed directly. This can be helpful when wanting to modify the state of a value type stored inside the set without removing and readding it.
Yup, that's fine. Close and Dispose do exactly the same thing on the desktop framework. If I remember correctly, I only used Close because of some old platform issue.Also there was this line:
loopFinished.Close();
Close does not exist for an AutoResetEvent I changed this to Dispose() instead. Is this acceptable? I tried looking online, but I couldn't find much.
You could also just delete the ParallelLooper entirely and supply another IParallelLooper implementation that wraps existing thread pools if they offer an efficient parallel for loop. The TPL's Parallel.For works great for this purpose; I only implemented the ParallelLooper because of platform holes.Finally all the threads were changed to tasks
I am not entirely familiar with the underlying mechanics of Task.Delay, but if it's functionally similar to Thread.Sleep, then it will work correctly. However, performance may be a problem. Certainly in the case of the spin wait, a Sleep or a blocking wait could produce nasty results, like surrendering the time slice too aggressively. The waiting portion of the SpinLock is probably best replaced by the SpinWait structure.Thread.Sleep was changed to Task.Delay inside of the spinlock class. The Thread.SpinWait was also changed to a Task.Delay, although if I read right between the differences in spinwait and sleep that is probably not the best thing to use, however I believe it should work correct?
However, I would recommend just getting rid of the custom SpinLock entirely, and replacing its usages with the PCL-included SpinLock. This is yet another spot where the custom implementation only exists because of old platform support holes.
As you've encountered, there's not too much, just these areas left over from ye olde early XNA days. Reducing or eliminating the pain for PCL is something I'd like to do, but I have a history of doing a poor/slow job at maintaining compatibility across a lot of simultaneous targets. It's looking like v1.4.0, which I expect to package up as the stable release in the next couple of months, is going to be the last version which tries to maintain backwards compatibility with Xbox360 and WP7.I'm extremely interested in a portable subset version of BEPU Physics. What's the likely hood of this happening soon? Would it be possible for me to port it over myself or is there a lot to change?
v2.0.0 will probably be the next version and will toss out as much cruft as possible, so it should be easier. (That, and early fiddling implies it will probably be at least twice as fast on many simulations, before taking into account SIMD types )
Re: Portable Subset
The file still exists in the folder and when I created my new project I added it in not realizing it. The quick set is still there for sure.
Hopefully I can test it out soon! I'll try to post some screenshots/video/code when I get a chance.
I might change this in the future.You could also just delete the ParallelLooper entirely and supply another IParallelLooper implementation that wraps existing thread pools if they offer an efficient parallel for loop. The TPL's Parallel.For works great for this purpose; I only implemented the ParallelLooper because of platform holes.
Quite an easy fix as well just renamed the SpinLock class and added in the missing references.However, I would recommend just getting rid of the custom SpinLock entirely, and replacing its usages with the PCL-included SpinLock.
Hopefully I can test it out soon! I'll try to post some screenshots/video/code when I get a chance.
Re: Portable Subset
Oops, yup- for some reason I thought the Xbox360 had eventually added that. Guess not! The QuickSet is expected.The file still exists in the folder and when I created my new project I added it in not realizing it. The quick set is still there for sure.
Notably, the WINDOWS compilation symbol should be safe to use when compiling for PCL. It's a bit of a misnomer in these post-XNA times; it just stops the HashSet wrapper from being used as well as a few other Xbox360/WP7 oddities.
Re: Portable Subset
I'm getting an error on locker.Exit():
Error: Unexpected exception while executing a micro-thread. Reason: System.Threading.SynchronizationLockException: The calling thread does not hold the lock.
The stack trace:
at BEPUutilities.DataStructures.ConcurrentDeque`1.TryDequeueFirst(T& item) in BEPUutilities\DataStructures\ConcurrentDeque.cs:line 114
at BEPUutilities.ResourceManagement.LockingResourcePool`1.Take() in BEPUutilities\ResourceManagement\LockingResourcePool.cs:line 95
at BEPUphysics.PhysicsResources.GetSimulationIslandConnection() in BEPUphysics\PhysicsResources.cs:line 171
at BEPUphysics.Constraints.SolverUpdateable..ctor() in BEPUphysics\Constraints\SolverUpdateable.cs:line 141
The line numbers might be slightly off from the original code after my edits. I tried to look up the error but I am afraid it's a bit outside of my threading knowledge. Any ideas for this issue?
Error: Unexpected exception while executing a micro-thread. Reason: System.Threading.SynchronizationLockException: The calling thread does not hold the lock.
The stack trace:
at BEPUutilities.DataStructures.ConcurrentDeque`1.TryDequeueFirst(T& item) in BEPUutilities\DataStructures\ConcurrentDeque.cs:line 114
at BEPUutilities.ResourceManagement.LockingResourcePool`1.Take() in BEPUutilities\ResourceManagement\LockingResourcePool.cs:line 95
at BEPUphysics.PhysicsResources.GetSimulationIslandConnection() in BEPUphysics\PhysicsResources.cs:line 171
at BEPUphysics.Constraints.SolverUpdateable..ctor() in BEPUphysics\Constraints\SolverUpdateable.cs:line 141
The line numbers might be slightly off from the original code after my edits. I tried to look up the error but I am afraid it's a bit outside of my threading knowledge. Any ideas for this issue?
Re: Portable Subset
That is peculiar; it implies that locker.Enter was not called. I would recommend first verifying that TryDequeueFirst calls Enter properly... but if it does, then I'm not sure.
Re: Portable Subset
I tried:
but no luck still fails on the locker.Exit(); which is odd if it successfully locked.
Code: Select all
public bool TryDequeueFirst(out T item)
{
bool taken = false;
//locker.Enter(ref taken);
locker.Enter(ref taken);
if (taken)
{
try
{
if (count > 0)
{
item = array[firstIndex];
array[firstIndex] = default(T);
firstIndex++;
if (firstIndex == array.Length)
firstIndex = 0;
count--;
return true;
}
item = default(T);
return false;
}
finally
{
locker.Exit();
//locker.Exit();
}
}
item = default(T);
return false;
}
Re: Portable Subset
Oops, I remember now:
1) The PCL SpinLock is a struct.
2) The locker field is readonly.
3) Calling Enter mutates the struct.
4) The attempted mutation of the struct creates a local mutable copy that isn't stored back into the readonly field.
5) Later Exit operates on the unmutated field value.
So, if you remove the readonly it should work.
1) The PCL SpinLock is a struct.
2) The locker field is readonly.
3) Calling Enter mutates the struct.
4) The attempted mutation of the struct creates a local mutable copy that isn't stored back into the readonly field.
5) Later Exit operates on the unmutated field value.
So, if you remove the readonly it should work.
Re: Portable Subset
Perfect I have a character controller interacting with my static world mesh. It seems to work perfectly! I'll try to get the code uploaded as soon as I port over the character controller demo.