Announcement

Collapse
No announcement yet.

Unity Is Growing Their LLVM Compiler Team As They Try To Make C# Faster Than C++

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

  • #31
    Originally posted by oleid View Post
    I wouldn't like to see C++ to be the main language for Android development, either.
    I would but not on merit of the language. But instead entirely on the homogeneous nature of all code bases. We could basically stick to one language for *everything* which in the "games industry" happens to be C++. As it stands now:

    1) Win32 - C++
    2) iOS - Objective-C++
    3) Android - NDK / NativeActivity (C++)
    4) Web - Emscripten (C++)

    Like this, we can share so much code between projects. Imagine using the "premier" languages as the following:

    1) Win32 - C#
    2) iOS - Swift
    3) Android - Java
    4) Web - Javascript

    We couldn't share sod all. What a bloody waste of time! No porting opportunity. Why do people do this?

    I don't particularly like Java but if every single project on earth would switch to it as a language, I would be very happy with that.

    It is rarely about our "enjoyment" when it comes to programming, it is all about not having to rewrite shite pointlessly XD.

    Same with spoken language to be fair. I am a native English speaker so obviously prefer that language over others but if the whole world switched to i.e Danish, I would be more than happy to learn it. Holidays around the world would be so much better!

    Bringing this topic back to Unity slightly, I highly recommend using Microsoft's C++/clr compiler rather than C# for the .NET bytecode. Getting locked to C# is really crappy for portability.
    Last edited by kpedersen; 09 April 2019, 05:33 AM.

    Comment


    • #32
      Originally posted by kravemir View Post

      Uhm.. No,.. The problem with Android apps is that they are bloated,.. if Google had picked c++ as the primary language for Android alps, then it would have proved how c++ is unstable, buggy, and memory eater (due to memory leaks). I personally saw android developers who don't care to write sane code even in Java.. I wouldn't like to see them writing c++ apps..
      Speaking as someone who's been forced to code in Ada for the past 8 years: Going back to C/C++ is hard. Yes, it's portable, but it's really overdue that the language gets retired for everything except maybe low-level interfaces. It is not fun to use, and the shorthand syntax that pretty much *every* C developer uses make figuring out what programs are trying to do much more difficult then necessary. (Sorry, I'm used to ImAVeryLongAndDescriptiveVariableOrProcedureName now.)

      Comment


      • #33
        Originally posted by atomsymbol

        Consider the following code found in a compiler implementation:
        Code:
        struct Jump final : Instruction {
        // Does ptr==shared_ptr OR ptr==weak_ptr ???
        ptr<Instruction> target;
        };

        Note: Imagine that `Instruction` has 100 subclasses representing various machine opcodes.
        I agree in general but in this case, (am I understanding this correctly?) the answer here strongly suggests a weak_ptr because:

        1) target (almost by definition of its name) suggests that this Jump class does not own this data. It is referring to existing data to point to.
        2) In contextual terms, the Jump instruction navigates to the target instruction. This must exist and "be owned" elsewhere, and thus does not need to be held here as a shared_ptr
        3) This is basically a good example of aggregation. The target instruction exists regardless of if this Jmp instruction points to it. Composition here makes no sense because they are independent instructions.

        In the case of instructions, I think they should never hold onto each others data (as shared_ptrs) because even though they may point at one another, they are still all held (in effectively a flat list) with the concept of an assembly object.

        I tend to use this as a quick reference guide. Player can target other players but cannot possibly own them (Aggregation). A player has weapons glued to his hands which he cannot possibly drop. So he "owns" their data because they are part of him (Composition).

        Code:
        struct Player
        {
          weak_ptr<Player> target;
          shared_ptr<Weapon> weapon;
          Weapon offhand;
        };
        But yes, you are absolutely right, sometimes you cannot easily make this choice. But I especially notice it when wrapping C libraries.

        Code:
        struct Texture
        {
          shared_ptr<OpenGLContext> context; // Because if OpenGL deletes its game over for the underlying data (GLuint) regardless of reference count
          GLuint id;
        };
        
        struct OpenGLContext
        {
          std::vector<shared_ptr<Texture> > textures; // Because if any of these delete, bad news because they might be currently bound in OpenGL's stupid state system
        };
        Here you get a cyclic reference. In this case, I would use an intermediate class to hold them both (as shared_ptrs) and then let that go out of scope at the end of the program. Still a bit naff though. This solution is actually most similar to the single flat list (#2) in the first example solutions.

        That said... a garbage collector in this case would be even worse because it cannot handle native C memory, especially stored on a GPU any better. No current way to scan a GPUs stack memory for references. The Java jogamp / gluegen bindings are... complex to get round this and end up just holding on to as much as possible to prevent it from being GC'ed.

        So as usual it leads me to state that after all these years, C++ is still pretty crappy. However it is still the best we have :/
        The later standards are not making it any better either, most of the features are gimmicks like auto, lambdas, modules and other javascript-like "quick buck" concepts.
        And don't get me started on safety; I am writing a "safe" debug STL just to tell me when the language has managed to kick me in the teeth again. Just to prevent even the most basic errors (like this: https://github.com/osen/sr1/blob/mas...gling_this.cpp) when dealing with massive codebases.
        Last edited by kpedersen; 09 April 2019, 12:10 PM.

        Comment


        • #34
          Holy shit so many terms for pointers which are just... pointers. Just fucking use raw pointers, christ. This crap is so much over-engineering for dummies.

          Comment


          • #35
            Originally posted by atomsymbol

            I am waiting for a C++ compiler that will print a warning in such cases.
            I think PVS-Studio (https://www.viva64.com/en/pvs-studio) is the closest to a compile time check. Never used it personally.

            Valgrind is good but I often get tired of porting my software to Linux (from either BSD or Windows) just to use it haha. I have too many false negatives when I use it on FreeBSD. Or too many false positives when using NVIDIA drivers. Intel Parallel studio / VTune misses most errors IMO. My favorite; Rational Purify is hard to get hold of these days.

            What is quite interesting is that Valgrind misses around 10% of the memory breakages in my "hall of shame" test suite.
            The more mechanical nature of my std::sr1 library means it runs faster (even when active during debug) and it is guaranteed to catch most of these issues. Valgrinding large games and real-time engines is... painful

            I put it past the C++ ISO standards guys but they did not see much value in a "debug version of the stl" and also didn't seem *that* interested in safety compared to speed and features which was a little disappointing.

            Originally posted by Weasel View Post
            Holy shit so many terms for pointers which are just... pointers. Just fucking use raw pointers, christ. This crap is so much over-engineering for dummies.
            Raw pointers are no good for modern C++. Consider this:

            Code:
            Player *p = new Player();
            std::string bob = "My name";
            delete p; [B]// May never reach here[/B]
            An std::bad_alloc exception could be thrown on the bob line meaning that as the exception propagates and stack unwinds, you never get to call delete on p.
            You could litter the code with try / catch but since C++ has no "finally" keyword, you will also probably be duplicating a lot of code.

            Plus there aren't many pointers... Just shared_ptr. The others are only there for its short comings / failures . If shared_ptr was perfect, there would only be one pointer type and I am sure C-style pointers would be officially deprecated.

            For me, safety is much more important than speed. Besides, in my experience, I could write the slowest C++ code possible and still come out faster than the most optimized Java. Jeez, only recently Java stopped having to use the heap for everything haha. The algorithm came with Java 8.. Escape Analysis.

            When you see things like glm no longer zeroing out basic structures like vec4 just for "ultimate speed" and artificially disabling compiling on compilers as recent as Visual C++ 2012 (not even the standard but the brand, wtf :/), you can really see that C++ is starting to be ruined by people. And yet it is *still* the best choice for most problem domains haha

            Don't get me wrong, raw pointers are fine, if binding C code or out right writing in C. Otherwise you can take a step back, look at a massive codebase... and know somewhere... someone... has fscked up with a raw pointer XD.
            Last edited by kpedersen; 10 April 2019, 06:13 PM.

            Comment


            • #36
              Originally posted by kpedersen View Post
              Plus there aren't many pointers... Just shared_ptr. The others are only there for its short comings / failures .
              Different pointer types makes sense to express different semantics. Consider shared_ptr vs unique_ptr vs weak_ptr.
              • A shared_ptr uses atomic reference counting internally. That's expensive, but needed in multi-threading contexts.
              • A unique_ptr always has only one owner. Always. It cannot be copied. Only moved. Thus, it's perfect for passing ownership of heap-allocated objects. Which is something you cannot do with shared_ptr. (at least not compiler-assisted).
              • A weak_ptr is a reference to a shared_ptr. It can be used for e.g. modeling caches. You load something from hard drive, pack it into a shared_ptr and pass around weak_ptr. If memory pressure is high, that shared_ptr can be dropped safely and if anyone holding a weak_ptr is still using it (by temporarily converting it to a shared_ptr) it gets destructed later.


              Originally posted by kpedersen View Post
              If shared_ptr was perfect, there would only be one pointer type and I am sure C-style pointers would be officially deprecated.
              They will never be deprecated, as they are needed for C interfaces and of course internally in pointer abstractions.

              Comment


              • #37
                Originally posted by wizard69 View Post
                You guys are off on a tangent here with memory management, I’m rather shocked that a company like Unity would even bother with C#. Maybe it is the circles I travel in but C# seems to be very dead as a language. I can’t imagine that they will get a rush of developers to work on C#.
                Here's the top 15 languages according to Stack Overflow. C# is seventh, but the only real competitors it has ahead of it are Java and Python.

                Suffice it to say, there are a lot of C# developers out there. They just tend to be mostly on Windows, rather than working on OSS linux applications.

                JavaScript 67.8%
                HTML/CSS 63.5%
                SQL 54.4%
                Python 41.7%
                Java 41.1%
                Bash/Shell/PowerShell 36.6%
                C# 31.0%
                PHP 26.4%
                C++ 23.5%
                TypeScript 21.2%
                C 20.6%
                Ruby 8.4%
                Go 8.2%
                Assembly 6.7%
                Swift 6.6%
                Last edited by smitty3268; 27 April 2019, 10:44 PM.

                Comment

                Working...
                X