AndyL

A few questions for Shawn or one of his buddies:

1/ Does the register allocator used in the XBox JITter use all of the available scalar floating point registers If not, how many can it deal with

2/ Does the XBox VM ever skip array bounds checking, and if so under what conditions

3/ Presumably there are no bounds checks when using unsafe code and pointers

4/ Are the method inlining limitations of the CF VM mentioned here still applicable to the XBox VM - especially the one about not inlining any method with floating point arguments or return values (yikes, that would be all floating point setters and getters!)

Andy.



Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

I'm not Shawn or one of his buddies, but I am pretty sure I know the answers to most of these:

1) No clue

2) Almost certainly never. If it did I would consider that a security hole and a bug. The CLR always checks bounds unless you are unsafe. If it did not, then the entire .Net security model falls to pieces as it is critical that the CLR JIT'r emits bounds checking code right along with the native instruction equivalents of your IL. If it did not, then your code would not be prevented from using buffer overrun attacks.

3) Assemblies with unsafe code / pointer use won't load on the 360 because they are, ummm, unsafe. ;-) The security model of the appdomain won't allow such an assembly to load, and for good reason. Fortunately, you can write performant C# w/o the use of unsafe code. In my experience, you should be more concerned about garbage collection than bounds checking....especially in the CF!

4) No clue...and I'm eager to hear the answer to this one as well. I'm betting the answer is the same limitations apply though.

Frankly I wouldn't worry about such performance things before writing code. Write your code first, profile it, then fix the hot spots. Chances are it won't be the lack of inlining or the bounds checking that is slowing you down. If it is, then you can always "fix" these by making your code ugly after the fact. ;-)

My attitude towards building performant .Net code is keep in mind things like object life and number of instantiations up front; that stuff tends to be hard to rewire later, and is almost certainly always a performance issue. As for the other stuff, I write my code the way I'd like to see it: elegant and easy to maintain. Only when a profiler tells me later that such code has a performance issue will I hack it up and make it ugly in order to make it fast.

Frankly, it's just too hard to "guess" what will be a bottleneck when still writing the code. Sure, when writing code it's easy to say "Hey, if I could definitively inline this, it would be faster", but will it really matter My attitude is trust the CLR, let it do it's job, and build your code the elegant, maintable way. Only when you have proof that it has let you down in a way that matters to your app do you hack the code up to make it faster.

Just my 2 bits...

On a related note, what I would like to hear is what ways, if any, the CF360 folks have altered GC on the CF to work for the 360 version. Any significant changes to the GC could have significant impact on the performance of applications, and assuming that the GC works the same as it did in the CF if it in fact does not could result in XNA developers making the wrong assumptions.

- Ryan





Re: XNA Framework JIT register allocation and bounds checking

AndyL

Ryan,

I'm pretty sure you don't! Fact is that only the VM guys could possibly know the answer.

2/ Array bounds checks are often hoisted out of a loop on the desktop VM, so that the array bound checks can be skipped within the loop.

3/ Unsafe code is fine on the XBox.

Yes you should wait until you know where the bottlenecks are, but hey - might it just be possible I have written something like this before I'm doing some pretty complex physics, and trust me, stalling the CPU pipeline will kill performance on the 360 CPU. Thats why transforming a vector via a 4x4 matrix takes 5x longer on the XBox than on the PC, unless you deal with it, and why I need answers to these questions. There is a 10x speedup on the XBox if you get things right...

 





Re: XNA Framework JIT register allocation and bounds checking

Jon Watte

3/ Unsafe code is fine on the XBox.


Really Have you tried it If unsafe code is fine, then you can pretty easily(*) take over the box, as it allegedly runs in supervisor ("kernel" or "ring 0") mode.
I was under the impression that unsafe code would not be allowed to be deployed/loaded through XNA onto the Xbox.

(*) for some value of "easily"






Re: XNA Framework JIT register allocation and bounds checking

AndyL

 Jon Watte wrote:


Really Have you tried it If unsafe code is fine, then you can pretty easily(*) take over the box, as it allegedly runs in supervisor ("kernel" or "ring 0") mode.
I was under the impression that unsafe code would not be allowed to be deployed/loaded through XNA onto the Xbox.

(*) for some value of "easily"

Yes Jon, of course I have tried it  - the VM is sandboxed in some other way, the exact details of which haven't been disclosed.





Re: XNA Framework JIT register allocation and bounds checking

Jon Watte

Interesting. Thanks for the data point!





Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

Replies...

2) Sorry I was being overly simplistic. Yes, there are special cases when it is deterministic from analyzing the code that it is impossible for you to walk off the end of the array, because as I stated it's the CLRs job to guarantee that you can not, so it always bounds checks (either physically every single access, or logically by pre-checking when it knows the code can't walk off in subsequent accesses). For example when loops are unrolled this can happen depending on what you are doing in the loop.

If you are trying to nail down the precise conditions of when it makes these determinations so that it can affect how you craft your code, I suggest you think twice about it at any point, and most definately at any point before the tuning phase. I say this because leveraging unpublished, priviliged information is not always wise. Due to it's very nature it is also subject to change without notice since it never was published. There is no contract in play to be honored.

The 360 hardware may be static, but the 360CF doesn't have to be. In fact it will possibly change every time the XNA Framework revs. If an implementation detail were to change, your specially crafted loop may then run slower; not faster, especially across CLR impl's. Therefore it is wise to construct your code in a manner that is consistent with what the language and designers intended. Over time this is likely to be the best performing code, and will certainly always be the most maintable. Crafting non-intuitive code to take advantage of an unpublished implementation detail to eek out a few extra cycles is not wise. The only time I would consider doing this is during tuning phase after I had hard evidence that said code was a major bottleneck and rewriting it non-intuitively and taking advantage of unpublished implementation details would reap a significant performance boost.

3) Have you tried unsafe code on the xbox I have not, but I have definately read that it can not be done; I'm pretty sure here on the forums. Just because you can check the "unsafe" check box does not mean the code will run. I would be *amazed* that it would. When you check the unsafe checkbox it causes the unsafe flag to be set in the manged module metadata. If the 360CF allows such assemblies to load it's a whopper of a secuirty hole that would probably be exploited eventually. I would consider it a defect if the 360CF allowed unsafe code to load.

The bottom line is any XNA game on the 360 bypasses an exhaustive Certification Process (CP). One major goal for the exhaustive CP is to find any bad code (intentional or not) that can affect the users experience, not only for that game, but for the integrity of the entire system including other saved games, digital media, etc. However, since XNA itself went through the CP, it should not be possible to write games with it that defeat the spirit and one of the primary goals of the CP to begin with. I assume one of the reasons the CP folks allowed XNA through is a) it's sandboxed and b) it's locked down. Unsafe code violates this, and therefore XNA games would not be "certified" safe by-proxy.

If unsafe code is allowed to run on the 360, then the CP is truly bypassed. In theory, somebody would be able to implement a buffer overflow exploit and gains control of the system and could then do something malicous outside the sandbox. The chances of this happening accidentally are low. However, the chances of this happening intentionally from a hacker approaches 100% given enough time and motivation. After all, the #1 rule in secure programming is you assume the worst up front.

One could incorrectly argue that "Well, only Creators Club members can be affected, they take on extra risk by running XNA games". In addition to being incorrect, that's simply not the right attitude; it's dangerous. The 360 is marketed as a family entertainment device and has multiple profiles, removeable media, and competitive network play. Unsafe code buffer overrun exploits could be used to destory digital media that does not belong to the Creators Club member, or could be used to give the Creators Club member an unfair advantage (ie cheating).

I'm not saying that it would be easy for somebody to find and take advantage of these exploits. But it would not even be possible if the unsafe is not allowed (shy of a bug in the CLR). Again, using proper approch to security programming, you assume these bugs exist and the exploits are possible. Therefore you do not allow unsafe code.

If unsafe code is allowed today on the 360, it's either

a) due to a bug and will be fixed

b) due to a poor design decision by somebody who wasn't concerned about security, and will be fixed once exploited becuase somebody didn't follow the first rule of secure programming.

As such, if this works today I would not count on it working forever and as such would not recommend using unsafe anywhere. The bottom line is if you pay attention to the things that really matter, it shouldn't be unnecessary to use unsafe to get a high-performance game.

In Summary, as I mentioned before, worrying about bounds checks (and using unsafe code and pointers to avoid them) and inline functions (and using parameterized public fields to allow inlining where it normally would not occur) is inherently non-productive; at least up front.

In my experience it is far more effective use of ones time to concentrate on good algorithms and reducing GC impact, and don't worry about the other stuff until the tuning phase, once you can measure how much of a problem these issues really are (or are not!).

- Ryan





Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

AndyL if that is true, it scares me. A lot. I can't imagine it's not a bug. Even if it was by design, it'll be considered a bug once exploited. ;-)

If this was intentional, and what you describe is true, then this reeks of security through obscurity: if the details of the protection mechanism can not be disclosed without violating security, then it is not secure. Second rule of secure programming. As such, since it's easy to disassemble the 360CF CLR, a an exploit would come eventually.

Jon is correct here. Assuming the NETCF CLR runs in ring 0, and assuming unsafe code is allowed, then there is no protection mecanism in place that can't be overcome; it's just a matter of finding it and disabling it or jumping around it. It's really that simple. There may be some tricks that are being done to give the illusion of security, but I doubt very much it is secure if the details of the tricks can not be disclosed.

Look at the original XBOX. The only thing that kept it secure (for the brief time that it was) was the lack of knowledge that TEA was used. As soon as that bit of knowledge was gleaned (and rumor has it it was determined via human intelligence), a known vulnerability (aka the enabler) in the cipher was used immediately to break into the box. The exact thing applies here. Unsafe code represents a known vulnerability (the enabler). Once the obscure part is determined, the vulnerability can be exploited.

As soon as one person either reverses or talks to somebody "in the know" and gets the secrets of the obscure mechanism, they'll be able to use the unsafe code exploit to disable the protection mechanism and have their way with the box. If this gets out and is huge and generates horrible press for MS, it could kill XNA. Not worth the risk IMO.

Disabling a known good, publicly secure mechanism and replacing it with a "security through obscurity" mechanism that can't hold up to public scrutiny is absurd. I'd gladly give up 10% fps to know the system wasn't vulnerable in this manner.

If I'm wrong, MS can always prove it by publishing the details of the "protection mechanism" that allows unsafe code to run safely. If it's secure and can't itself be defeated by unsafe code, there is nothing to hide.

- Ryan





Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

Wow, what happened to Andy's reply to me from 8:31 (I have a local copy saved) Andy, did you delete it If so, very cool...my faith in your net forums skills is restored. ;-)

Dave, if you yanked it, don't worry I wouldn't have flamed back. :-P Please do not delete this one as I would like Andy to read my apology.

Andy, since clearly you were upset at one point, I want to apologize if I offended you. I also want to point out that these are public forums, and in the absence of somebody addressing you directly by name (which my two posts do not do but this paragraph does), you need to realize that somebody is making statements to the community, not to you personally. As such, you really should not have gotten offended as I was not attacking you or lecturing you, but I apologize that you did get offended.

In particular, as you know, not everybody has as much experience as you do. XNA has drawn a lot of new developers, and the last thing they need to do is start worrying about tuning then they don't have a fun, playable demo, much less a complete game ready for tuning phase. A newbie could look at your post and rightfully determine that this is an expert talking here, but that does not mean they should be concerned about these issues. At least not at the beginning. There is plenty of time for tuning later if they ever get a playable demo.

The last thing the XNA community needs is people getting bogged down in these perfmance tweaking details, becoming discouraged and ultimately abandoning their fresh ideas. Ideas that AAA studios will never dare to fund. Ideas that could change the industry (for the better for a change). The point of my post was to diseminate advice that would help ensure that doesn't happen.

We now return you to our regularly scheduled debate as to why the CF360 allowing unsafe code is the worst idea since New Coke. ;-)

- Ryan





Re: XNA Framework JIT register allocation and bounds checking

Jon Watte

I've got an archive of Andy's post. It was a little blunt, but also made a few good points about assumptions.

Assuming the NETCF CLR runs in ring 0

First, there is nothing called "ring 0" on the PowerPC, although my PPC kernel hacking days ended, oh... 7 years ago I forget what it's called; I think it's called "supervisor mode" but could be wrong.

Second, I'm not sure we can assume that. I don't have a 360 devkit, so I can't tell for sure; I was mostly going on what I know from the original Xbox SDK, and various back channels on the 360. It's quite possible that the CLR actually just sets the CPU to user mode, and lets the hardware take care of not allowing 'sploits. Make all code read-only, verify the few system calls you'll need to make (such as hard disk driver, given that you don't want to grant access to the disk from any code), and you can create a pretty tight system.

However, with that realization, writing a tool that probes pages to figure out what lives where would be possible. Just for fun, of course :-)






Re: XNA Framework JIT register allocation and bounds checking

AndyL

Forum skills Like hijacking someone elses thread to make your own point to 'the community' The fact was that the question was explicitly addressed to Shawn.

BTW, I pulled the reply (rather like you did by the way - you think I didn't notice ) in the hope you had got the message and I didn't want to leave it there to rub your nose in.

 'I'm not Shawn or one of his buddies, but I am pretty sure I know the answers to most of these:' sure sounds like a reply to me personally, given I asked them.





Re: XNA Framework JIT register allocation and bounds checking

AndyL

 Jon Watte wrote:
I've got an archive of Andy's post. It was a little blunt, but also made a few good points about assumptions.

After receiving the same post twice, without even a nod towards asking what it is that I am working on, I think 'blunt' was called for.





Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

Andy, [note the direct salutation]

I took the high road once Andy. Now I'll do it again (well, maybe not quite as high-road ;-). There won't be a third time. If you want to reply to this, take it to email.

I didn't think one could hijack a thread by discussing things that are on topic. However, posting off-topic flame-bait is a great example of hijacking a thread. Good thing you had a change of heard and deleted it. But unfortunately it seems you've found a way to hijack your own thread. How's that working for ya

FYI, I didn't pull any reply. I tried to reply to your post, but it failed because you had yanked it; but it seems that the forum software still sends out the IM notifications . If you want a copy I'll send it to you, this forum software eats posts so I always save everything locally first (in fact I don't even use this editor; it's too painful). I'm not going to repost it as I don't want you to flame again and get this thread locked (or have you just delete it after you had a change of heart).

Yes, definately a hearty thank you for pulling your post for my benefit. I don't think my ego could have handled it hanging out there any longer. It touches me that you care so much for my mental well-being that you would pull a post that shows you in such poor light...all for my benefit!.

Or perhaps, just maybe, you felt ashamed at what you posted Or it would get killed Perhaps Nah, that can't be right. That would be too much like admitting you were wrong by posting it to begin with. We can't have that! Instead let's just say you were afraid of the damage it was doing to me. That's the ticket! That saves face. Everybody will believe that. Why wouldn't they It makes perfect sense!

OK, that's enough sarcasm for now. In fact that's enough for this post, I think I've made my point. If you want to pursue this further, take it to email. There is no sense in getting this thread locked as both of us have some good questions in it that I'd like to see get answered. In particular, I'd like to see some published info on the 360CF GC; ideally the same level of detail as Richters excellent CLR book. That information may actually be useful before coding the game if there are substantial GC differences.

- Ryan

P.S. Like my new .sig ;-)

* Building a high performance 3D physics engine is not hard. Proof They are everywhere.

* Building a distributed in-memory database that scales linearly (< 5% deviation) from 1 to 1000 nodes is hard. Proof None exist.





Re: XNA Framework JIT register allocation and bounds checking

ryan.rogers

Agreed Jon, I know almost zilch about the PowerPC architecture. But as you point out, it has something similar in concept. Whether called kernel, or supervisor, or whatever, there has to be some form of elevated mode that the OS scheduler and certain drivers run in I would think. So even if the CLR ran in user mode, it is foolish to assume that there are no other bugs in the 360 OS and exposed api's that can't be exploited by a user mode app to trick it's way into kernel mode capabilities. Sure it would have to be a bug, but it would be a bug that would have been occluded by the CLR if unsafe code was not allowed.

Your last point is exactly my point as well. Allowing unsafe code to run is a big-time enabler As soon as you allow unsafe code to run by Joe Hacker who only has to plunk down $99, then that is another way to get in and start reversing the system and looking for defects to exploit. Plus, he already has the perfect enabler to exploit those defects with the ability to buffer overrun. In the future, he'll probably have a nice distributation mechanism available as well.

Ryan





Re: XNA Framework JIT register allocation and bounds checking

AndyL

Ryan, I'm sorry that you feel so upset that I said I found your posts patronising - I should have been a little more subtle. You might however want to take a look at how you started your last post and see if that might have come across in the same light

My point (bluntly put I admit) was that leaping in with an opposing view of how to go about solving my problem, without checking first what the issue is and what experience the author of the post has, might well come across in the way mentioned above, especially so if you don't appear have any experience in that particular field and the advice is rudimentary (albeit sound in a general context).

I apologise for being so direct and any offense that may have caused - and accept your previous apology if it stands.

 ryan.rogers wrote:
P.S. Like my new .sig ;-)

* Building a high performance 3D physics engine is not hard.  Proof   They are everywhere.

* Building a distributed in-memory database that scales linearly (< 5% deviation) from 1 to 1000 nodes is hard.  Proof   None exist.

Very funny, obviously taking a trip to the moon must be easy too .

Like mine

* Show me a collision detection system that scales linearly and I'll show you a distributed in-memory database that scales linearly.