#Accessing static data from burst compiled function

1 messages · Page 1 of 1 (latest)

open inlet
#

Hello !
I currently have a static class with methods that are used everywhere in my game so I need them to be as fast as possible. That's why I was using the [BurstCompile] attribute whenever possible. But there is a problem I still haven't been able to solve : how to access the static arrays that contain all the data needed for the methods. No matter what I try, it always leads to burst errors 😦
So far I've avoided the problem by passing the arrays as arguments to the methods but it is becoming more and more ugly and hard to maintain as more features (that require new data) are added to the game.
Is there something I don't understand ? Would anyone have an idea of how I should structure my data and methods to solve this problem in a cleaner way ?

#

It's becoming REALLY bad 🥲

public static bool _Raycast(in float3 origin, in float3 direction, float distance, in int4 dynamicMask, out float3 position, out CubeNormal normal, out int objectHit, out bool dynamicObject,
        in int sizeX, in int3 bigSize, in NativeArray<int> solidMicroBlocks, in NativeArray<int> solidMicroBlockIndexes, in NativeArray<int> bigBlockIDs,
        in NativeList<int> SPOIndexes, in NativeList<int> SPOMicroBlockIndexes, in NativeList<int> SPOMicroBlocks, in NativeList<int3> SPOPositions, in NativeList<int> SPOSizes, 
        in NativeList<int4> DPOBigBlocks, in NativeList<VoxelBoxCollider> DPOColliders)
#

And it's even worse when a job calls a method that calls another method and so on for example 😦

hollow surge
#

did you consider grouping the arrays in another structure? for example

struct RaycastParams
{
  int sizeX;
  int3 bigSize;
  NativeArray<int> solidMicroBlocks;
  NativeArray<int> solidMicroBlockIndexes;
  NativeArray<int> bigBlockIDs;
  //... etc.
}
open inlet
#

That's a good idea !
But I still find it weird to have to pass static data of that same class when calling its methods 🥲

#

But you're right that grouping everything in a struct will make it less ugly 😅

open inlet
#

Oh I've just found out about SharedStatic 😮
I can put the struct in a SharedStatic variable 😁

hollow surge
#

if that works for you, great! 🙂

kindred plank
#

sharedstatic is very easy to screw up, fwiw, since it has no safety checks to help with race conditions. i would ideally only use it on the main thread. when writing my own main-thread bursted code in user projects, i usually stick with a void* to a struct and then UnsafeUtility.AsRef inside the bursted function

#

then if you ever call the function in more than one situation you're less likely to have one invocation stomp on the results of another

open inlet
#

Is there something I do wrong ?
Field declaration :
private static readonly void* data2 = UnsafeUtility.Malloc(sizeof(CubePhysicsData*), UnsafeUtility.AlignOf<CubePhysicsData>(), Allocator.Persistent);
Assignment of data :
UnsafeUtility.AsRef<CubePhysicsData>(data2) = new CubePhysicsData(microBlocks, microBlockIndexes, bigBlocks);
Getting the data :
UnsafeUtility.AsRef<CubePhysicsData>(data2).bigBlockIDs[bigX + (bigZ << WorldManager.horizontalBits) + (bigY << (2 * WorldManager.horizontalBits))];

hollow surge
#

it says you're calling functions that aren't allowed to be called from static constructors; I'm gonna guess on the line of allocating data2? Move it to some system's OnCreate or something like that perhaps

open inlet
#

Ooh OK, I didn't understand it like this but now that you say it it makes sense !
I'll try that tomorrow, thank you ! 🙂

open inlet
#

So Burst will complain when accessing it 😢

hollow surge
#

that doesn't ring a bell for me, but I never tried something like that so I can't really help you ^^"

open inlet
#

If I'm not mistaking, Burst can only access static readonly variables, it's really annoying 🥲

#

There's always something that doesn't work 🥲

#

But shared statics seem to work so it's good for now 🙂

#

I'll just have to be careful not to schedule a job while I modify the data

old igloo
#

This is pretty much a terrible idea btw.
How can you sure your job is complete before you write your data

#

You really shouldn't use this for anything but constant data

open inlet
#

And I really don't see how I could do it in a safer way. I can't really copy the data every time, it's a few hundred mo 🥲

#

I made my own voxel collision system so it contains all the data about the terrain and all objects, it's a lot 😅

old igloo
#

There's just no real reason to use a static for this

open inlet
#

But then how do I access it ?

old igloo
#

Just pass it in as a field

#

Put it on a singleton - have automatic dependency management between your systems

open inlet
#

But then when I call these functions I need to access that data to give it to the function. So it would be static anyways 🥲
I really don't understand how to not make it static. These functions are used everywhere in my game.

old igloo
#

The functions exist on the same struct that has the data that you pass in

knotty mauve
#

It seems like we have the same problem, I have a static SingletonUtilities which create a singleton entity and will attach any singleton component/buffer to it.
Should I use "sharedStatic" in this case? I haven't read a thing about it

open inlet
#

So if I understand what you're saying, you have a struct in a static field and pass it to the functions as an argument ?

#

Personally since I discovered shared statics, I find them even easier to use.
I don't see how there could be more risk, in both cases the function accesses a static struct anyways. And it's more convenient because it doesn't have to be passed as an argument 🙂

#

But I might not understand everything you said, I hardly know anything about entity, components and systems, all I know is how to burst compile a static function and a job 😅

knotty mauve
# open inlet So if I understand what you're saying, you have a struct in a static field and p...

nah no, SingletonUtilities is a singleton struct (original idea from this video: https://www.youtube.com/watch?v=PRfFjvULgY0).
The reason why it is struct: "struct is unmanaged", that was what came into my head when I made it.

Clip taken from The Hot Path Show ep. 5 - https://www.youtube.com/watch?v=Ol3IQHh2p4E
Subscribe to Turbo Makes Games for new episodes of The Hot Path Show - @TurboMakesGames
Support The Hot Path Show - https://www.patreon.com/TurboMakesGames
Join us and other data-oriented developers on Discord: https://tmg.dev/Discord

▶ Play video
knotty mauve
knotty mauve
open inlet
open inlet