Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 28 Jun 2004
Offline Last Active Nov 25 2015 01:03 PM

#5263278 C# System.Numerics.Vectors slow?

Posted by Mike.Popoloski on 23 November 2015 - 11:30 AM

First, due diligence: are you sure you're actually running 64-bit? By default new projects get that dumb "Prefer 32-bit" option checked, so an AnyCPU build will still run using 32-bit. Also, make sure if you've got the debugger attached that you don't have it set to inhibit optimizations. By default most optimizations are disabled even in release mode when a debugger is present, for obvious reasons.


Also, be careful about which package you're using. The JIT looks for a very particular assembly to enable intrinsics, so if there is a mismatch in which build you're using it will just not optimize it. Doesn't .NET 4.6 ship with an older System.Numerics.Vectors assembly built in, or is it still recommended to grab one from NuGet?

#5239888 [SlimDX] Information on the history of SlimDX

Posted by Mike.Popoloski on 12 July 2015 - 06:35 AM

It's been almost 8 years exactly since my first commit. I was 17 at the time, still in high school, and therefore had a ton of free time on my hands. You can see in that initial announcement thread that I found myself interested (I had only recently gotten into C# and was playing with MDX). I PMed Promit, offered to work on DirectInput and got commit access (suspiciously easily actually. I think the idea of avoiding DirectInput work outweighed the fact that he didn't know me very well).


I didn't know C++/CLI at the time. It's an incredibly bizarre language and I'll do anything in my power to avoid using it on any project I ever work on again. I dug up an old journal entry where I list a few random quirks and then this one where I talk about the insanity of friend assemblies in C++/CLI. Fun times.


The fact that I had so much free time first in high school and then in college after that meant that I ended up doing the bulk of the tedious wrapping code. Poor Promit and jpetrie already had day jobs and had to come home and put in more work at night. From looking at the repo, I was responsible for Direct3D11, DirectInput, DirectSound, XAudio2, RawInput, X3DAudio, XAPO, D3DCompiler, Direct2D, and DirectWrite. Also lots of other random junk; the D3DX animation stuff is still a distant nightmare for example. We also ended up with a collection of neat little tools; one for counting lines, another for generating release notes, documentation, and website junk. There's one in there I remember writing to work around a crash in Microsoft's PIX tool where you couldn't run it on managed x64 assemblies.


At some point I made us an icon; it's been set as my avatar image ever since.


As Josh alluded to earlier, we had a great persistent bug in our memory allocator that we eventually tracked down. It's one of those ones that will stick with us probably forever. I eventually went back and replaced that whole system with the one that's still in use today. We very often need temporary space when marshaling parameters, so stack allocating that space is key to good performance. Unrelated: when wrapping some of the hairier parts of DirectInput I took a look at what MDX used to do and discovered some hilarity.


Right around the end of 2009 / beginning of 2010 development started to slow down. The library was stable, fast, and covered almost everything in DirectX, and a good deal more on top of that. Shortly after that MS released the June 2010 SDK, which was the last DirectX SDK drop. We worked for another year or so polishing things up, at which point MS announced Windows 8 and discontinued the SDK. Nobody on the team was interested in Windows 8, so we went into what was essentially maintenance mode.


Working on SlimDX was a ton of fun. It felt good to be working on a project lots of other people would actually find useful, and probably cemented in me my love of developing libraries and middleware. Every once in a while we'd discover some game or project was using our library. That SlimDX.dll would pop up in very surprising places over the years.


Working on the project was also a great way to network; I joined the #gamedev IRC around that time and got to know jpetrie, Promit, and Washu pretty well. Later on jpetrie recommended me for a job at ArenaNet out in Washington, so SlimDX was essentially my ramp into the games industry. The number of people I'd randomly meet who knew of the project was surprising. When I was at ArenaNet, we'd occasionally interview people who had used the library and had listed it on their resume. When we interviewed our audio programmer he started talking about how he had used it for his own personal audio projects he was working on. Going back further, one day I was in class at school, and the kid in front of me had the SimpleTriangle tutorial open and running on his laptop. We ended up becoming friends and roommates for the rest of my three years there based on that.


The SlimDX team has since moved on to different things, but I think we all still look back fondly on the project. We stepped up at the right time and provided a good product for people who needed it. The last binary release we did, in January of 2012, has over 500,000 combined downloads. I don't know if we'll ever take it further or even if we'll work on something different together; Josh is off in OSX land these days and Promit is swamped with shipping indie-ish games for mobile. I've been helping out with improving and wrapping a low-level graphics library developed by a former ArenaNet colleague. I feel like this is probably the way to go for any future game projects I work on.


Thanks for the interest; it's always fun to take a trip down memory lane.

#5239221 Advanced font/text rendering options

Posted by Mike.Popoloski on 09 July 2015 - 08:27 AM

Pango is a higher level library that draws together a collection of lower level libraries, including FreeType. You can do much the same thing yourself by just pulling in what you need. For the advanced OpenType shaping and layout stuff (GPOS and friends) you want the HarfBuzz library. DirectWrite is basically a combination of HarfBuzz and FreeType for Windows (with other stuff thrown in, like higher level font selection based on family names). It's not a great idea if you need to be cross platform though, as you've mentioned.


Most games don't even bother with scalable glyph rendering like you get with FreeType, let alone go into even more advanced layout and shaping, which is why you're going to have a hard time finding resources on it. Even with those libraries, applications like web browsers consistently have a hard time getting things perfect for all of the languages they support.

#5227498 C# class library and external functions

Posted by Mike.Popoloski on 06 May 2015 - 06:42 AM



Actually no, you would override the minus operator


If you were following framework design guidelines you would do both; the operator is convenient but some CLR languages might not be able to use them, so having a corresponding method is good form.

#5223660 Why high level languages are slow

Posted by Mike.Popoloski on 16 April 2015 - 07:31 AM

Hang on, what is all this "fighting the language" nonsense that keeps getting bandied about?


I won't speak for Java, but C# at least was designed up front for value types, pointers, and blocks of native memory. There are several whole keywords that exist solely for working with unsafe code. In fact, there's essentially no code you can write in straight C that you also cannot write in C#, (save for hideous macro tomfoolery). I do this fairly frequently for scenarios where memory layout is key; allocate a block of native memory and carve out some structs (value types) from within that block.


Granted, this kind of coding isn't *as* pretty as writing code that doesn't care at all about memory, but when you do care it's not all that hard to write. If you consider it a fight, then *every line* of C that you write is an equivalent kind of fight. The difference is that C# gives you the option to descend to that level; it turns out that a huge majority of the code that we write doesn't actually get run thousands or millions of times in a tight loop, so you don't much care how well it performs as long as it's fast enough.


If you're really paranoid about the GC kicking in when it's not wanted, tune it down or turn it off altogether for sections of the game that need low latency.


Want some native code generation so that we can get rid of JIT startup costs and get the benefits of having all damn day to optimize the code? Got you covered bro. Want to avoid taking a large dependency on the whole framework and having to ship that to end users? No longer an issue. SIMD? I hardly even know her!


Let's not even get started on multithreading. If it's a fight in C#, then it's the charge of the goddamn Light Brigade in C.

#5223236 PerfectMMORPG

Posted by Mike.Popoloski on 14 April 2015 - 03:29 PM

Pirate_Lord did it better: http://www.gamedev.net/topic/481176-pirate_lords-thread/

#5217428 Using csharp and directx i'm getting devicelost exception. How can i solv...

Posted by Mike.Popoloski on 18 March 2015 - 02:15 PM

Device Lost scenarios are well known phenomena in Direct3D 9. They generally occur when you lose exclusive access to a device, such as Alt+Tabbing out of full screen. If you're developing a D3D9 application, you need to specifically handle these cases by releasing resources, testing whether you have device access, and when you get it back resetting the device and reloading all GPU resources. If you want to go down this path, search around in the documentation for the proper way to handle device loss.


That process is at least as annoying as it sounds; you should consider whether you actually *need* Direct3D 9 support. You can support the same classes of hardware with the much newer Direct3D 11 API, which does not require handling of device loss and reset. The downside is that D3D11 is not supported on Windows XP, but since that OS is almost completely dead at this point, that's probably not a huge loss for you.

#5216040 C# Interview test "failed"? Why?

Posted by Mike.Popoloski on 12 March 2015 - 06:04 AM


...and that vec3 isn't a c# thing as we have a native vector3 class.

Vector3 is a Unity-specific thing (well, other game frameworks like XNA have similar vector types).

I wouldn't call any of them native - C# and .Net's core libraries don't have any built-in vector types that I know of. The Windows-specific class libraries like WinForms and WPF have vector/point classes, but I wouldn't consider them to be native either.





Still in beta, but will probably ship with the new RyuJIT runtime.

#5193966 C# .Net Open Source

Posted by Mike.Popoloski on 21 November 2014 - 08:23 AM

The GC may be amazing, but why is barring you from having any control an amazing feature? Wouldn't it be nice if you could choose to opt in to specifying the sizes of the different heaps, hinting at good times to run the different phases, specifying runtime limits, providing your own background threads instead of automatically getting them, etc? Would it harm anything to allow devs to opt in to that stuff? Do the amazing features require the GC to disallow these kinds of hints?


You can do a lot of that now. You've always been able to hint that a new collection should be run (which you might want to do right after loading a new level, say). Newer versions of .NET let you disable the GC and turn it back on again for sections of your code, so you could leave it disabled for your main loop and then flip it back on again during level load. There are different levels to this feature as well; you can set it to *never* run, or set it to "low latency", where it almost never runs unless you get critically close to running out of memory. You can also manually compact the LOH, letting you choose good times to reduce fragmentation.


If you want even more control, like taking full control of thread scheduling of the GC or setting size limits, you can host the CLR, similar to how Unity works. There are a crazy amount of knobs to tweak there.


Of course, the simplest advice that avoids all of this is what it has always been in both the managed and native worlds: during the main loop of your game, don't heap allocate. Not necessarily easy, but simple to understand. It's certainly easier to do in C++, but also doable in C# (in fact, it was almost a hard requirement that you do that for Xbox Arcade XNA games, since the Xbox's GC was pretty crappy). Unlike in some other managed languages that will remain unnamed, the .NET CLR supports value types, so you can with just a bit of effort cut down heavily on the amount of garbage you're generating.


For the times you absolutely need heap allocations but really need to avoid the managed heap, you can always just *allocate native memory* anyway! There's nothing stopping you from malloc-ing some native memory blocks and doing your work there. I do this pretty commonly in my own projects for certain classes of memory where I need explicit control over lifetime or alignment.

#5075821 99 Bottles Of Beer Challenge With Least Amount Of Characters ?

Posted by Mike.Popoloski on 06 July 2013 - 06:56 PM


What? Wait... what? Can somebody translate that for me, because some things I didn't see yet in C# (or I saw but didn't have the need to use hence forgot it).

It's mostly some very clever applications of string formatting.


That said, Mike clearly knows way more fun facts about string formatting than I do smile.png



Oh, the things you learn by trawling through the MSDN documentation at random :)   So many bits of the BCL are completely unknown to most people.

#5075789 99 Bottles Of Beer Challenge With Least Amount Of Characters ?

Posted by Mike.Popoloski on 06 July 2013 - 02:51 PM


Also, I think C# and Java should include their using/import and class definitions.


I did, they add ~20-30 characters to your character count.



Actually, with the Roslyn shell you no longer need the surrounding class / Main function cruft, just as if you were using the python shell. Granted, you should still include the using statements, since they're required.


Also, I see your 300+ C# entry and raise you 250 (even beats some of the other languages)  biggrin.png

string f="{0:#;;",e=".\n",o="s;s;''} of beer",w=" on the wall",n="o more} bottle",x=n+"{1:"+o;
for(int a=99;a>=0;)System.Console.WriteLine(f+'N'+x+w+", "+f+'n'+x+e+
"{1:Take one down and pass it around;Go to the store and buy some more}, {1:#;99;n"+n+"{2:"+o+w+e,a,a-1,--a-1);

It doesn't require the conditional operator either, which is nifty.

#5074523 DirectWrite and DirectX 11

Posted by Mike.Popoloski on 01 July 2013 - 01:55 PM

It's a fairly straightforward concept, just lots of moving parts to deal with. Essentially you implement a custom ITextRenderer interface and plug it into DirectWrite, so the dwrite text layout engine says "here are the glyphs you want, and here is where you should put them".  Then it's up to you to render them at those spots. 


That library uses another piece of DWrite, a BitmapRenderTarget, to render each glyph to a memory buffer and then packs it into a Direct3D texture atlas using a bin packing algorithm. Then you have a texture atlas with various rendered glyphs, and you have positioning info, so you can just draw quads at those spots with the correct texture coordinates and it all works.

#5070293 C# timing code not functioning properly

Posted by Mike.Popoloski on 16 June 2013 - 05:40 PM

The TimeSpan struct defines a "tick" as exactly 100 nanoseconds long. In contrast, the Stopwatch class uses the performance counter built into the machine, and thus its frequency varies from system to system. You should use the Stopwatch.Frequency field to convert your delta ticks to seconds.


N.B. You can cache the Stopwatch.Frequency value on startup, since it's guaranteed not to change while the system is running.

#5064696 Optimizing code statements into expressions?

Posted by Mike.Popoloski on 24 May 2013 - 11:36 PM

There is so much wrong with this thread that it's mind boggling.


I have no idea why you think trying to force some random statement into an expression is going to make things faster, but it's really not. Trying to play tricky games with a language that compiles to an intermediate bytecode is also just laughably futile.


Furthermore, C# * absolutely* can be inlined, but you're not going to find it on the IL level, since it's a feature that's handled by the JIT and the CLR. It's also probably going to be a lot smarter about when to do it than you would be, taking into account the adverse affects it can have on polluting the instruction cache and potentially spilling registers in tight loops.


Additionally, boxing and unboxing are not going to have much of a performance hit on your application unless you're doing a ton of them. Allocations in a garbage collected environment are very fast, and small short-lived temporary objects are one of the best-case scenarios for the typical managed GC. It's unlikely to cause any fragmentation problems, considering that the GC moves objects in memory to avoid that very issue.


It's also not difficult to avoid boxing calls. Your nine thousand line program is actually pretty small as far as most games go, and it's absolutely possibly to avoid any boxing operations in a code length of that size, depending on what you're doing. As Frob said, if you find yourself needing to do it often, you need to critically rethink your design.


Despite all that, if you actually needed every single cycle available to you (and I'm not convinced that in your case you do), you should be working in a language that facilitates that kind of development, such as C++. Probably you're going to keep misguidedly doing what you're doing, but if nothing else this post should help others who might stumble upon this thread.

#5048890 Issue trying to create a shared resource

Posted by Mike.Popoloski on 01 April 2013 - 10:15 AM

I'm not too experienced with using the shared resource stuff, but I think that if you want it shared, you need to use the ResourceOptionFlags.Shared flag, not the KeyedMutex flag.