Announcement

Collapse
No announcement yet.

Miguel de Icaza Calls For More Mono, C# Games

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #91
    Originally posted by BlackStar View Post
    First, the GC is much more flexible than smart pointers.
    Besides that it's totally unpredictable and complex, it doesn't have much more than a false sense of lazyness to offer.

    Originally posted by BlackStar View Post
    Second, the GC allocations are ridiculously faster: they just increment a pointer. C++ new has to traverse a linked list, locate an empty spot, allocate it, then initialize a 'smart pointer' structure - that's much more complex than a plain pointer.
    C++ doesn't have to do all that. It could, for instance, do a memory allocation from the OS straight away. The GC won't buy you anything in this department. If memory allocations is on the critical line (fairly seldom in my experience) you're always better off doing a targeted optimization around the problem at hand. Trusting the GC is like hoping for luck besides trying to control the sweeps...

    Comment


    • #92
      Originally posted by Togga View Post
      Originally posted by BlackStar
      Second, the GC allocations are ridiculously faster: they just increment a pointer. C++ new has to traverse a linked list, locate an empty spot, allocate it, then initialize a 'smart pointer' structure - that's much more complex than a plain pointer.
      C++ doesn't have to do all that. It could, for instance, do a memory allocation from the OS straight away. The GC won't buy you anything in this department. If memory allocations is on the critical line (fairly seldom in my experience) you're always better off doing a targeted optimization around the problem at hand. Trusting the GC is like hoping for luck besides trying to control the sweeps...
      And what do you think VirtualAlloc et al do?

      Besides, you haven't thought your argument through: if memory allocations are not on the critical line, the GC will always be faster than manual memory management because it will not run at all. Contrast with RAII/smart pointers which will stupidly delete objects even if you have tons of memory available.

      Remember, the fastest code is the one that never runs.

      Comment


      • #93
        Originally posted by BlackStar View Post
        And what do you think VirtualAlloc et al do?

        Besides, you haven't thought your argument through: if memory allocations are not on the critical line, the GC will always be faster than manual memory management because it will not run at all. Contrast with RAII/smart pointers which will stupidly delete objects even if you have tons of memory available.

        Remember, the fastest code is the one that never runs.
        What malloc do is implementation dependent. Use an implementation that is fast (eg not Windows) and this should not be a problem, then you could also use threads without performace degradations.

        A memory free operation is very very quick (though OS dependent). With the GC you eventually get into a garbage collection sweep which can be very disturbing in a critical phase. Besides, if you want no free + sweep in C++ you can always do the sweep yourself, it's quite trivial.

        Performance should never be an agrument for a garbage collector out of your control. If you want performance, you're better off with doing it yourself in a controlled fashion. C# / .NET is not the choise for performance critical applications to begin with.

        Comment


        • #94
          Originally posted by BlackStar View Post
          Second, the GC allocations are ridiculously faster: they just increment a pointer.
          That's the theoretical best case scenario, in practice the managed heap get's fragmented and either need to be compacted which is very expensive (reordering data blocks in the heap) or it has to locate empty spots just like new/malloc.

          Originally posted by BlackStar View Post
          Third, RAII is eager whereas GC is lazy. This means that the GC is significantly more efficient when you have free memory (as it never runs). Once memory pressure builds, the GC will run once to collect n objects, which is *still* more efficient than RAII, which runs n times to collect n objects.
          This I can agree with, but you can take measures to ensure that the destruction of objects won't have a negative effect on the interactivity of your application since you are in control of when objects fall out of scope. Also you can easily implement your own heap/memory pool just as the VM does (and as you suggested further down as a way to work around the problem with GC pauses) and instead reclaim the allocated pool as one big chunk when you are no longer in need of it.

          Also saying that the GC doesn't run when there's 'free memory' is untrue, it's constantly running. It constantly monitors the amount of free memory in it's heap and scans for objects falling out of scope, obviously this is much less costly when it doesn't find anything that needs collecting or if there's enough free space in large chunks available for it not to do a compaction but even then it's not zero cost. And as soon as it is put under pressure all bets are off, which is why you are forced to code around the garbage collector in order to be certain that the interactivity of your application won't be hampered by GC pauses.

          Originally posted by BlackStar View Post
          Ever heard of Unity3d?
          From what I read it uses C# as one of three supported scripting languages, the actual framework is written in C++. How does that translate to C# being 'so damn popular in this scene'? If that's all you got then your claim is obvious hyperbole.

          Originally posted by BlackStar View Post
          Compared to the performance you need to create a good game.
          Well since 'good' is purely subjective then you can write a 'good' game in anything since 'good' does not imply any kind of performance demand. As far as performance goes C# (atleast in the Mono incarnation) is slower than Java and Go, much slower than C/C++/ObjC, but faster than pure scripting languages.

          And please don't think I am against Garbage Collecting, I see it as a useful tool but not as a silver bullet that is the appropriate/best solution for all needs and in many situations I think it creates more problems than it solves, particularly where performance is paramount. The language I'm planning to do a project in next is Go and it's fully garbage collected.

          Comment


          • #95
            Originally posted by XorEaxEax View Post
            That's the theoretical best case scenario, in practice the managed heap get's fragmented and either need to be compacted which is very expensive (reordering data blocks in the heap) or it has to locate empty spots just like new/malloc.


            This I can agree with, but you can take measures to ensure that the destruction of objects won't have a negative effect on the interactivity of your application since you are in control of when objects fall out of scope. Also you can easily implement your own heap/memory pool just as the VM does (and as you suggested further down as a way to work around the problem with GC pauses) and instead reclaim the allocated pool as one big chunk when you are no longer in need of it.

            Also saying that the GC doesn't run when there's 'free memory' is untrue, it's constantly running. It constantly monitors the amount of free memory in it's heap and scans for objects falling out of scope, obviously this is much less costly when it doesn't find anything that needs collecting or if there's enough free space in large chunks available for it not to do a compaction but even then it's not zero cost. And as soon as it is put under pressure all bets are off, which is why you are forced to code around the garbage collector in order to be certain that the interactivity of your application won't be hampered by GC pauses.


            From what I read it uses C# as one of three supported scripting languages, the actual framework is written in C++. How does that translate to C# being 'so damn popular in this scene'? If that's all you got then your claim is obvious hyperbole.


            Well since 'good' is purely subjective then you can write a 'good' game in anything since 'good' does not imply any kind of performance demand. As far as performance goes C# (atleast in the Mono incarnation) is slower than Java and Go, much slower than C/C++/ObjC, but faster than pure scripting languages.

            And please don't think I am against Garbage Collecting, I see it as a useful tool but not as a silver bullet that is the appropriate/best solution for all needs and in many situations I think it creates more problems than it solves, particularly where performance is paramount. The language I'm planning to do a project in next is Go and it's fully garbage collected.
            It seem that Mono is slow, but there are no real numbers and theoretical discussion. In fact starts with a half-truth your answer: "the expensive reordering" is as simply as moving pointer from Nursery to Gen0 (or old generation for Mono). The full reordering appears much rarely in Full-GC cases. Even it would be a "catastrophic" 0.1 seconds break (Mono is possible to tune the heap size for SGen to have stable full GC time, as .Net too).
            But Mono even it would be as popular and as useful as was Visual Basic 6, that would still make it desirable for Linux. In fact most criticism like "applications start slow", are either circumvented by a simple AOT compilation that Mono documents it:
            Code:
            sudo su
            for i in /usr/lib/mono/gac/*/*/*.dll; do mono -O=all --aot $i; done
            I posted this code, to also test by counting how many native images you will found and their space usage, to make a good assumption about how much C# code is in class library of Mono. And don't worry, is the same in .Net. Most of code in .Net is amazingly written in .Net. The load-fast feedback is mostly because libraries moved in AOT, are precompiled in advance. If you use Ubuntu at least, and not a nightly version, and at times you use Mono applications, you may get good startup times. It is also great if you use it with MonoDevelop and Banshee.
            The utterly slow garbage times are not reflected when using for real life MonoDevelop, or SharpDevelop (my favorite IDE for most development at home). Even more, Mono gives a great performance baseline for mobile phones (which are "slow" at least for todays standard), is certainly faster than Android's JIT, it is close to Objective C in OpenGL.
            Is it slower than Java? It may be so, but most of the times, when we say slower than Java, we mean Java -server, as is comparable with Java -client.
            But even it would be slower, the premise it would be wrong, there are great applications and games written in C#, I remember the Neverwinter Nights 2 Campain Editor, that was written in C# (I know because at times it shows the exceptions which were .Net like ), and the bottleneck in the video card, not the C# side.
            In fact if we talk about games at least, if you want to make it cross platform, depends on the platform, and if is not Mac OS X, anyone will use VM based IDEs, for Android you need a Java based IDE, for WP7, XBox, Windows you will use VS which have good parts written in .Net.
            At the end I do recommend to consider Paint.net/Pinta, if performance is the standard we judge Mono. I did use Pinta with "--llvm" and the gains were in 0-15 % realm for applying filters (I have a fork in my computer) compared with "-O=all" (LLVM backend vs the Mono's full optimizations profile). Of course, there is no C++ based painter that is genuinely better than Paint.Net/Pinta in a small package I know on Windows/Linux, or radically faster, and if is really faster, is because of orther features, like using GPGPU or CPU Intrisics (for using SSE2-SSE4x, which are reflected in Mono.Simd namespace in Mono) (software like Adobe Photoshop CS), but not because of C++ codebase in itself. Pinta in fact is a great example why Mono should be used, there is no lag because of "evil Mono" will do a GC, even at times it does, but because you can develop it so well in Windows with powerful tools (because VS have so good tools for code analysis, bug tracking, and so on, that people can contribute quality patches and everyone would enjoy its real usage, not ranting about how slow it is.
            Dear XorEaxEax, I understand you think that performance is crucial, do you use the same performance principles on other projects? Like you go to Blender's site and say them to write the plugins in other language than python, or would you investigate all bash scripts and rewrite in a "lighter" C++ that do the same thing, to have real, tangible startup performance? Will you suggest Gimp to remove their Python and Lisp scripting that can increase with 5% startup time of their dialog? Don't forget about Vim (it can be scripted with Python) and Emacs (scriptable with Lisp). And if you think that those are side projects, don't forget then to say to Mozilla, about their JetPack and the XUL to be fully removed, C++ FTW. And if you happily you use Chrome, say to them that V8 should not bootstrap the library in JavaScript, but to write it in C++, and in a similar way to go to Libre/OpenOffice to remove the possibility to write not only Java plugins, but also Python (there is a project in LibreOffice to rewrite Java extensions to C++ or Python). At least based on your efforts, anyone will benefit the 0.5 second startup time (once any VM is loaded, is shared in memory, so no extra IO would be gain of performance) and an imperceptible extra performance from dialogs and plugins written in complex tools, like Blender or Office. Imagine the gains, think global not just a simple game...
            Last edited by ciplogic; 19 February 2012, 06:22 AM.

            Comment


            • #96
              Ciplogic covered the performance part well, so I'll just reply to this:
              Originally posted by XorEaxEax
              From what I read it uses C# as one of three supported scripting languages, the actual framework is written in C++. How does that translate to C# being 'so damn popular in this scene'? If that's all you got then your claim is obvious hyperbole.
              • The PlayStation Suite SDK uses C#
              • The free XBox360 SDK uses (what else?) C#.
              • In the official Google NaCl release, 4 out of 7 demos were written in C#.
              • Almost every open-source game engine comes with a C# binding.


              I'd say C# looks pretty popular in this scene. C++ is obviously king, but C# comes second and appears to be growing in popularity.

              Comment


              • #97
                Almost every open-source game engine comes with a C# binding.
                And it's bitrotten and unmaintained in half of them, again testifying to C#'s popularity?

                Comment


                • #98
                  Originally posted by ciplogic View Post
                  It seem that Mono is slow, but there are no real numbers and theoretical discussion.
                  I saw a benchmark of Mono vs Java and Go around the time Go was released where Mono was quite far behind both in the tests they performed, I'll try to dig it up, meanwhile Language Shootout (it's not a perfect measure I know, but it's not worthless either) shows the same:

                  http://shootout.alioth.debian.org/u6...re-fastest.php
                  http://shootout.alioth.debian.org/u6...re-fastest.php

                  That Mono is overall quite a bit slower than Java was to be expected as Java is quite performant for managed code, I was surprised though seeing Go beat Mono already given that it is younger.

                  Originally posted by ciplogic View Post
                  In fact starts with a half-truth your answer: "the expensive reordering" is as simply as moving pointer from Nursery to Gen0 (or old generation for Mono). The full reordering appears much rarely in Full-GC cases. Even it would be a "catastrophic" 0.1 seconds break (Mono is possible to tune the heap size for SGen to have stable full GC time, as .Net too).
                  Not really following this part, the VM managed heap gets fragmented aswell, and given that it is much smaller than the heap managed by the operating system it gets fragmented faster. When it gets fragmented the GC will have to 'look for empty spots' and not just increment a pointer a la stack. When it gets really fragmented and it can't find a suitable spot it will have to perform compaction (ie moving memory blocks around to make room), and of course the worst is when the VM heap runs out of space entirely and has to ask the host OS for a bigger block of memory, that's really slow.

                  Originally posted by ciplogic View Post
                  Paint.Net/Pinta in a small package I know on Windows/Linux, or radically faster,
                  Last time I checked, Paint.Net relied on the native code GDI+ library to handle the heavy lifting. Also are there any benchmarks which compare Paint.Net with for instance Gimp? (not that I think a paint/photo edit program is in any way a good candidate for benchmarking)

                  Originally posted by ciplogic View Post
                  Dear XorEaxEax, I understand you think that performance is crucial, do you use the same performance principles on other projects?
                  No not at all, I work professionally in Python (and C/C++) so I know full and well that there are tons of situations where performance is not paramount and being able to deploy code faster and with less debugging is preferable. But there are also tons of situations where performance actually is key or atleast has a great impact on the useability of the program, and I would not use languages like Python, C#, Java in those situations. At the end of the day, if program A does the same thing as program B, but faster and using less memory then I will use program A, that doesn't mean that I or someone else will always think it's wortwhile to write program A and instead settles for the performance and memory usage of program B.

                  Originally posted by ciplogic View Post
                  Like you go to Blender's site and say them to write the plugins in other language than python, ...
                  Of course not if they aren't hampered by performance, would you write the new cycles renderer in Python, C# or Java? No, because it needs to be as fast as it can be, same goes for a ton of other things in Blender, like the physics engine, particles, subdivision modeling, etc.

                  Originally posted by ciplogic View Post
                  And if you happily you use Chrome, say to them that V8 should not bootstrap the library in JavaScript, but to write it in C++
                  V8 is a javascript engine which is written in C++ and compiles Javascript into machine code before running it, how this example would benefit your argument is beyond me.

                  I have no problem with people writing code in C#, I have no problem with people writing games in C#, I did argument against BlackStar claiming that C# was _particularly_ good for writing games, while also citing performance as one of the benefits. Mono by everything I've seen is not fast relative to other languages used for writing games, the garbage collector requires workarounds in order to assure smooth framerates. In short as I've said before, if you are a C# programmer then by all means why not use Mono to write your games if the performance is adequate for your project, however I can't see why anyone wanting to write games should choose to learn C# in order to do so unless they directly target XNA.

                  Comment


                  • #99
                    Originally posted by BlackStar View Post
                    • The PlayStation Suite SDK uses C#
                    • The free XBox360 SDK uses (what else?) C#.
                    • In the official Google NaCl release, 4 out of 7 demos were written in C#.
                    • Almost every open-source game engine comes with a C# binding.


                    I'd say C# looks pretty popular in this scene. C++ is obviously king, but C# comes second and appears to be growing in popularity.
                    For the Playstation Suite (just like with XBox Live Marketplace) they want managed code because they want to easily sandbox games written by 'indie' devs, so they could choose between C# or Java and went with C#. AAA titles which actually push the hardware of these consoles are written in native code (C/C++).

                    And almost every open-source game engine comes with bindings for pretty much every other language out there like Python, Lua, D, Vala, Go, you name it... it's certainly not something that sets C# apart.

                    Again what scene are you talking about exactly? Because overall C++ is king (that much we agree on), second I'd say ActionScript (flash), then I'd say ObjC due to the IPhone/Ipad inertia, and I'd say Java before C# given that it's the 'native' api of Android which these days is likely a much larger target of game development than XNA, but I could very well be wrong about that as I don't know how many Android developers use Java for games as opposed to say C++.

                    Comment


                    • Originally posted by XorEaxEax View Post
                      Not really following this part, the VM managed heap gets fragmented aswell, and given that it is much smaller than the heap managed by the operating system it gets fragmented faster. When it gets fragmented the GC will have to 'look for empty spots' and not just increment a pointer a la stack. When it gets really fragmented and it can't find a suitable spot it will have to perform compaction (ie moving memory blocks around to make room), and of course the worst is when the VM heap runs out of space entirely and has to ask the host OS for a bigger block of memory, that's really slow.
                      You are missing a few key points here:

                      (a) If the VM runs out of space, it asks the OS for more memory. This is exactly as fast as a plain calloc.

                      (b) Memory fragmentation does not decrease GC performance, it merely increases memory use. The GC does not scan for empty blocks ala malloc (which loses performance with fragementation), it really just increases the end pointer (which is O(1)), regardless of the existence ofo blocks.

                      (c) The .Net GC does not work like your common C++ GC, it is much more invasive and can do things that are simply not possible in the unmanaged world. For instance, the GC can move stuff around in memory and update all relevant references. (This is impossible in C++, because it's impossible to distinguish between a real pointer and a random number that happens to look like a pointer.)

                      So how does the .Net cope with memory fragmentation? Simple: it runs a a low-priority background thread that looks for empty blocks. If it finds one, it moves a suitable object in that block, thereby reducing memory consumption.

                      Since this is a low-priority thread, it doesn't actually impact performance! If there is enough CPU time, it runs; if not, it doesn't run until the OS scheduler gives it a timeslice - the worst that could happen is that the application uses a little more memory than it could.

                      Contrast this with C++, which will always fragment memory when you new/delete objects. In the extreme case, this will cause the application to run out of memory and die. This is a very real-issue for long-running applications and apps running in constrained environments (like a console). Solving this either requires lots of code or so-called "low-fragmentation" heaps (which also decrease performance (by doing double-indirections, in order to support compacting).

                      (d) not only that, but the GC can (and does) keep long-lived objects separate from short-lived objects, which further reduces fragmentation. This is a huge optimization you get for free. (You could try to emulate this in an unmanaged language through pool allocators, but this requires deep magic, lots of fragile code and time - that most people would prefer to spend on actual game code. And the end result will be less performant than a proper GC.)
                      Last edited by BlackStar; 19 February 2012, 01:55 PM.

                      Comment

                      Working...
                      X