Disable DebuggerStepThrough Attribute in Burst Intrinsics

I’ve been having a lot of fun with burst intrinsics lately, it’s a really cool way to learn more about intrinsics, assembly, and SIMD in general, and I find that the intrinsics C# reference implementation makes the topic super approachable. However, the DebuggerStepThrough attribute essentially stops me from being able to use the reference implementation to its full potential i.e. stepping through the function to understand how it actually operates. Is there a way to disable this attribute, or do I will I have to forever comment the attribute out to actually debug my code? Also, what’s the rationale for adding this attribute, if I want to step through the C# reference implementation line by line, shouldn’t I be allowed to do that?

Assuming you are using visual studio, this should be helpful: Debug user code with Just My Code - Visual Studio (Windows) | Microsoft Learn

Thanks, but I’ve tried that, and can’t get it to work, I can set breakpoints in the intrinsics with it, however, as soon as I hit f10 to step to the next line, the debugger jumps out of the intrinsic function. I see I forgot to include that in the original post.

The reasons we added the [DebuggerStepThrough] are:

  • We’re imitating actual hardware instructions with those intrinsics, so with Burst that’s a single instruction, and so we wanted the managed fallback to be the same.
  • The body of those intrinsics isn’t actually all that interesting - how we implemented the hardware instructions is not how they are implemented in hardware. All that really matters is that the results match.

Hope that helps explain the thinking behind it our end!

Thanks for taking the time to give your rationale. I see your points, though, from my viewpoint, it seems to limit the potential of the reference implementation somewhat. I know that the reference implementation is not how the instructions are implemented in hardware, however, isn’t a reference implementation essentially an: “It’s as if we did it this way, it’s not actually how we do it, but it’s as if”? That’s at least how I’ve always viewed reference implementations. With that view, it’s super convenient to step through the code and observe partial results to verify that I’ve understood what the intrinsic does correctly. Instead of wondering why I didn’t get the result I thought I would, and trying to run the code in my head/on paper, I can step through the code and much more quickly see where I misunderstood. I was originally under the impression that the reference implementation was steppable. This lowered the barrier enough for me to set aside time to try and learn SIMD through intrinsics when I previously considered it too intimidating in, for example, C++.

I just wanted to say, though, while it’s a small annoyance that I have to comment out those attributes to learn SIMD “my way” (guess I’m more annoyed at C# for having that attribute in the first place :P). It’s super awesome that the whole DOTS push also leads to Unity becoming a toybox for playing around with and learning “low-level” stuff with “high-level” tooling and conveniences, makes it way less intimidating and much more approachable.

2 Likes

I could see this being useful for analyzing the behavior of your own code in certain cases. Anyway, you can
pretty quickly modify the package code and remove the attribute - I think Unity only revalidates the packages on next editor restart.

Unity seems to revalidate it once after a change or something. I’ve written up an editor script that comments out the attributes for me, and I always have to run it twice per time I start Unity. First one time, then Unity revalidates the package, then I run it again and then the attributes stay commented out. Hopefully, they won’t fix it if that is unintentional.

At this point it sounds like it might be easier to just keep a locally modified version of the package (copy it from Library/PackageCache to the Packages folder and commit that to your repo).