Search Unity

Performance issues. How fast is C# in Unity compared to say, native C++ on a device?

Discussion in 'Scripting' started by Raccoonteur, Oct 25, 2017.

  1. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    I have no idea what you are saying sorry.
     
    hippocoder likes this.
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I know C++. It was my first language and I'm in touch with it on a regular basis during my studies.

    I can only repeat myself. All the components written in C# contribute to performance. Because they're also just a part of every single frame's computation.
    Graphics are only a part of it, there's alot of other non-graphic stuff that also needs computation. And then there are your behaviours.
    Profile your game and you'll see what it takes to compute a frame, behaviours are not "free", yet they do usually run fast enough on modern devices, so it's either bad code or complex game logic that performance suffers from.


    100 FPS aren't really special these days and that's not even relevant when we talk about C# vs C++, as there is neither a reference to compare this with (in a fair manner) nor does it say anything about the complexity and how well and fast it would run under ideal circumstances.

    I'm not sure why you always use this to explain everything. Technically you can do that - sort of -, and some games make use of the API that comes with Unity to generate various graphics-related objects that'll be send to the graphics card, but that's a different topic.
    That's got nothing to do with the actual topic though.
     
    Last edited: Oct 27, 2017
    hippocoder likes this.
  3. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    I can promize you, that there are zero C# codes that directly touches frames or any other graphical things. They touch codes that are made with c++ that touches things inn that order. It might seems that your C# impact your performance,but that is mostly memory things that is dealing with deep down engine core elements. Your scripting is just far in the backend, while a allot of otherthings happen, like example transform , Vector3 in c++ language .

    And yes technically you can not draw pixel by C# you type codes that compile in to c++ (or other low level) that draw pixel by the engine. If you working with c++ you should know this. C# by it self do nothing.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Neither did I claim you directly touch the render-pipeline with these calls, nor did I say you draw any part of the frame directly. You're completely missing the point.

    We were talking about scripts and C# vs C++, and I said that they do have an impact on performance. It's just a fact. You can't deny it. If you really believe that scripts do not have any significant impact, then there's no point in this discussion as it's just completely wrong.

    Erm, you call those functions and that has overhead, not only because you're usually copying data to the C++ side, but the C# API that's being offered also needs to perform various checks and other things like marshalling. Again, I'm not saying you draw anything directly with C# - this wasn't even part of the discussion and I'm not quite sure why it has become a part of this whole non-sense discussion now.
     
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    The things you're saying are either nonsensical or represent a fundamental misunderstanding of how the engine works.

    Honestly, you're just hijacking the thread now.
     
    RDeluxe and Suddoha like this.
  6. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    So this runs at 75 fps in the unity editor's game preview (might run faster for others, my computer is fairly lowend):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class LifeBehaviour : MonoBehaviour {
    6.  
    7.     const int width = 256;
    8.     const int height = 256;
    9.     const int texArraySize = width * height;
    10.     private byte[][] oldWorld = new byte[height][];
    11.     private byte[][] newWorld = new byte[height][];
    12.     private byte[]   texArray = new byte[texArraySize];
    13.  
    14.     void Start () {
    15.         for (int y=0; y<height; ++y) {
    16.             oldWorld[y] = new byte[width];
    17.             newWorld[y] = new byte[width];
    18.  
    19.             for (int x=0; x<width;++x) {
    20.                 SetState(x, y, Random.Range(0,2) == 0);
    21.             }
    22.         }
    23.     }
    24.  
    25.     void Update() {
    26.         SwapStates();
    27.         UpdateCA();
    28.         UpdateTexture();
    29.     }
    30.  
    31.     void SwapStates() {
    32.         var tmp = oldWorld;
    33.         oldWorld = newWorld;
    34.         newWorld = tmp;
    35.     }
    36.  
    37.     int IsAlive(int x, int y) {
    38.         return oldWorld[y][x] > 0 ? 1 : 0;
    39.     }
    40.  
    41.     void SetState(int x, int y, bool state) {
    42.         var s = state ? (byte)255 : (byte)0;
    43.         newWorld[y][x] = s;
    44.         texArray[x + y*width] = s;
    45.     }
    46.  
    47.     void UpdateCA() {
    48.  
    49.         for (int y=1; y<height-1; ++y) {
    50.             for (int x=1; x<width-1;++x) {
    51.                 int n;
    52.                 n  = IsAlive(x-1, y-1);
    53.                 n += IsAlive(x  , y-1);
    54.                 n += IsAlive(x+1, y-1);
    55.                 n += IsAlive(x-1, y);
    56.                 n += IsAlive(x+1, y);
    57.                 n += IsAlive(x-1, y+1);
    58.                 n += IsAlive(x  , y+1);
    59.                 n += IsAlive(x+1, y+1);
    60.                 if (IsAlive(x, y)>0)
    61.                     SetState(x, y, n==2 || n==3 );
    62.                 else
    63.                     SetState(x, y, n == 3);
    64.             }
    65.         }
    66.         //TODO: handle borders here!
    67.     }
    68.  
    69.     void UpdateTexture() {
    70.         var tex = new Texture2D(width, height, TextureFormat.R8, false, true) { filterMode = FilterMode.Point };
    71.         tex.LoadRawTextureData(texArray);
    72.         tex.Apply(false, true);
    73.         GetComponent<Renderer>().sharedMaterial.mainTexture = tex;
    74.     }
    75. }
    Built for PC it runs at about 165 fps for me (vsync disabled)

    EDIT: Manually inlining IsAlive() and SetState in UpdateCA sees me get 165fps in the editor and around 250fps running as a standalone PC build, so I'm a bit disappointed in c# not being more agressive with inlining that code itself (obviously it didn't if I got such an improvement)
     
    Last edited: Oct 27, 2017
  7. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Really? Your implying that C# scripting does the direct work for you? How is that even possible without a CLR or IL2CPP? Please explain that to me, and you better get that right else i call you a troller. I am not hijacking any thing, i am just putting things in right place, when ppl mix c# with game performance. Maybe you want to be constructive if its not to hard for you?
     
    Last edited: Oct 28, 2017
  8. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    This thread has gone off the deep end.
     
    Suddoha likes this.
  9. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Unity use native code by the CRL / IL2CPP / AOT, end of story..
     
    Last edited: Oct 28, 2017
  10. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Because it matters when we talk about performance.

    Don't mind the pun, but if you were an implementation of an allocator / memory manager, you wouldn't do a good job at putting "things in right place".

    Perhaps it's better to leave this thread alone now, it's getting nowhere *waits for the GC to collect me*.
     
  11. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    Can get 20fps more (about 275-280fps)with gross "unsafe" code, and profiling in the editor Update's total CPU is only 60% of the execution... I'd post the code but it's a bit shameful and no one seems interested.

    EDIT: Well I might as well post it then, I'm new and have no rep so what have I got to be ashamed of... (warning wear googles if looking at this to protect eyes)
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public unsafe struct foo {
    4.     public fixed byte World[65536];
    5.     public fixed byte World2[65536];
    6. }
    7.  
    8. public unsafe class LifeBehaviour : MonoBehaviour {
    9.     const int width  = 256;
    10.     const int height = 256;
    11.     foo foo;
    12.     private byte[] texArray = new byte[65536];
    13.     private bool swapBuff = false;
    14.  
    15.     void Start () {
    16.         fixed (byte* ptr = foo.World2) {
    17.                 for (int y=0; y<height; ++y) {
    18.                 for (int x = 0; x < width; ++x) {
    19.                     var s = Random.Range(0, 2) == 0 ? (byte)255 : (byte)0;
    20.                     ptr[y*width + x] = (byte)(s & (byte)1);
    21.                     texArray[y*width + x] = s;
    22.                 }
    23.             }
    24.         }
    25.     }
    26.    
    27.     void Update() {
    28.         UpdateCA();
    29.         var tex = new Texture2D(width, height, TextureFormat.R8, false, true) { filterMode = FilterMode.Point };
    30.         tex.LoadRawTextureData(texArray);
    31.         tex.Apply(false, true);
    32.         GetComponent<Renderer>().sharedMaterial.mainTexture = tex;
    33.         swapBuff = !swapBuff;
    34.     }
    35.  
    36.  
    37.  
    38.     void UpdateCA() {
    39.         fixed (byte* ptr = foo.World)
    40.         fixed (byte* ptr2 = foo.World2) {
    41.             const int h = height - 1;
    42.             const int w = width - 1;
    43.             int n;
    44.             byte* p, p2;
    45.             if (swapBuff) {
    46.                 p = ptr;
    47.                 p2 = ptr2;
    48.             } else {
    49.                 p = ptr2;
    50.                 p2 = ptr;
    51.             }
    52.  
    53.             p += width;
    54.  
    55.             for (int y=1, XY=width; y<h; ++y, p+=2, XY+=2) {
    56.                 for (int x=1; x<w;++x,++p,++XY) {
    57.                     p -= width;
    58.                     n  = *(p-1) + *(p) + *(p+1);
    59.                     p += width + width;
    60.                     n += *(p-1) + *(p) + *(p+1);
    61.                     p -= width;
    62.                     n += *(p-1)     +    *(p+1);
    63.                     if (*(p) > 0) {
    64.                         var s = n == 2 || n == 3 ? (byte)255 : (byte)0;
    65.                         p2[XY] = (byte)(s & 1);
    66.                         texArray[XY] = s;
    67.                     } else {
    68.                         var s = n == 3 ? (byte)255 : (byte)0;
    69.                         p2[XY] = (byte)(s & 1);
    70.                         texArray[XY] = s;
    71.                     }
    72.                 }
    73.             }
    74.             //TODO: handle borders here!
    75.         }
    76.     }
    77. }
     
    Last edited: Oct 27, 2017
    BlackPete and Suddoha like this.
  12. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    No it dosent, nor should it.. You just need to learn to code C# properly..

    Your pretending to be a moderator? I think that is against the forum rules. Your not the boss here. Yeah you gota wait really long for my 12kb gc to happen compered to yours. My GCFPS is pretty good how is yours?
     
    Last edited: Oct 27, 2017
  13. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Oh really... You better read what you've quoted in your previous post about JIT compilation, as it exactly prooves the opposite of what you're claiming. It helps to actually read articles completely, and also take a look at linked information ...
    Don't just quote something out of context because it looks as if it's just what you want it to be.

    Am I doing that? Where?
    It gets really frustrating to argue with you, as you don't even read properly...

    If that does not make it clearer: I was kind of talking to myself. Just another pun, as I thought about leaving this thread => I'm no longer needed => like an object that's no longer needed & reachable => garbage collection... Get it?

    Well, now it's not funny anymore. :<

    You're still wrong. Accept it.
     
    RDeluxe likes this.
  14. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Going personal just make you look immature, (pretty hard to read when you use wrong quote codes , "but i see you edited now". I said that your C# code doses not directly run your performance,
    as i proven that i needs to go in to CRL before it can run with the machine. Do i need to explain this deeper?
    FPS has nothing to do with your scripting, unless your doing a hell of allot things wrong and stressing the CPU. Graphics
    is GPU , logic is CPU. FPS depends on shader, and how you choice to render things. I understand you didn't get my GCFPS joke, this just prove how stupid this thread is, "how fast is C# fps etc.."

    If your game does allot of CG that impact performance i can tell you 100% your doing something really wrong.

    you can code c ++ to stress your CPU so it impacts GPU FPS, great,, no. Does c++ perform man better than c# script? No it dosen't .
    I am right? Yes i am ..


    You told me to leave the thread, you can boss your parents maybe but not me. I am going nowhere.
    You also replied faster than i could Finnish my post if you read it again.. to fast there, to little thinking. Maybe this is why you have GC issue? Are you using "using" in your C# ? do you know why we have "using" in c# just a simple example..

    Your not the boss of me. Go write c# properly thank you..
     
    Last edited: Oct 28, 2017
  15. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    I duno what some guys here are drinking that makes you think C# script is directly doing machine low level stuff. Its like saying when i turn the wheels on my car i acutely use my arm strength to do it. Totally ignoring that the car use a servo system doing the heavy lifting for you in the background. Sure you can drive your car in the dirt , it doesn't mean your servo is bad. It means that your driving blows..

    Any thing C# = IL = CPP .. forget your c# codes they all wrapped out in the end..

    So we have proof nr.1 ALL net.framework codes are compiled in to native code tru CLR.
    nr2: Unity use there own IL2CPP API (means IL to cpp) that is based on AOT compiler +VM. So you don't have to worry about performance from your script. all of this is CPU, FPS is GPU and render engine. So back to topic. How fast is C#? It dosent matter, C++ drives the speed. your script are converted in to c++ (prop most of your code will be wiped in the wrapper). Your not the driver. This is not even a discussion, its already documented by Unity https://docs.unity3d.com/Manual/IL2CPP-HowItWorks.html



    So how is your C# performance? ...
     
    Last edited: Oct 28, 2017
  16. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    I'll just leave this here: https://docs.unity3d.com/Manual/IL2CPP.html

     
    Suddoha likes this.
  17. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Wrong quotes? Edited? Immature? The post you're referring to has not been edited.
    And where am I getting personal? The pun?
    If I say you quote stuff out of context from a huge article of a Wiki-site, what's wrong with it? (that's what you quoted and responded to). That's just a fact, no offense at all. Don't make things up.

    If you want to imply that I'm stupid, go ahead. I know I'm not.

    If you're referring to my code: I've never said anything about my own GC in any of my projects or code bases / my framework.

    It can and it often does, especially when you do complex stuff. If you still don't believe that, hope's lost you'll ever accept that.

    Read above, so no, not 100% correct.

    I did not tell you to leave, re-read carefully and try to understand the post. I was referring to myself because there was no more need to reply to people who keep ignoring straight facts.
    And who's getting personal here? Can you stop addressing my parents? What the hell is wrong with you?

    Again you're getting personal.
    And I've never said that I have GC issues, where did you read that? Can you please take some time and actually read carefully? Gosh, I'm repeating myself...
    Answer: No, you obviously cannot. Your other posts in other threads have proven that as well, just like they proove how much pseudo-"in-depth"-knowledge you have about C#.

    Here are just two of multiple fundamentally wrong examples that YOU POSTED during the past weeks / months:
    Both completely wrong. And you tell people to "learn proper coding" and "understand C#" ? Don't be silly, stop trolling.

    Now back to your post once more:
    What are you trying to proove here? If you think "using" is relevant for performance, then please don't answer. You're just going to make fun of yourself. Stop being a clown.

    This being said, I'm finally glad I can come back to you with your own quote:

    Haven't been part of such a silly and useless flame-war for half a decade. Reminds me of good old MMO times when people freaked out because they had lost a battle.
     
    hippocoder likes this.
  18. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    RDeluxe likes this.
  19. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Really ? :) you didnt make a big mistake with your quoteing? You lie. Its not a big deal but you did mess up your qoutes and then edit it. Hence why it was hard for me to read

    Where did i say you where stupid? Your telling me i can't read. I said the thread is stupid not you..Go read your own quote

    This is becoming really pathetic, you defending that you didn't understand my joke?

    You did, you said. "Perhaps it's better to leave this thread alone now". Maybe you meant to say "Perhaps it's better I leave this thread alone now". Got it? Your first statement can easily be misunderstood, But its fine i understand what you tried to say no problem.

    This is not personal right?


    .
    lol more personal attack. You don't get it. you keep talking about GC as performance issue, that means you
    have some real issue with GC, still you pretending you know how things work, but you clearly don't..You can fool others but not me.

    What posts now? Are you stalking my posts in other threads? I help people who have issue, and they are happy when
    they get fixed, and yes allot of people code C# wrong. Allocation in update state etc, then complain about C# have low performance, both me and people i work with laugh at it..people who have worked with c# since start.

    None of your replys here have any technial spine, your just zipzas talk about post and digging your self down the whole with weaker arguments for each post you do. And you post allot of "nothing", how about talking abit more technical so you at least can have a decent argument? I don't want to talk about your parents or your lack of understanding my jokes.

    lol you have no idea what your talking about, "using" with IDisposible is because of performance control! lol are you for real?

    Aha, then i know who you are.. but you better up your tech talk with me. Right now its in a horrible condition.
     
    Last edited: Oct 28, 2017
  20. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    What the heck are you talking about now?

    Hippcocoder you bann me from the thread where i can not defend my self from harassment, and continues talk about me and my name can continue . Its not ok i contact the Unity directly to deal with this. Hippcocoder this is not ok for you to do.. You ether unbann me or bann Suddoha from the thread, if there be more talk about me without me being able to defend my self i start a case directly to does involved in that.. I can't belive that people tend to S*** talk when they can't keep there constructive argument on the subject AND getting supported by a forum moderator....

    You can't just bann a person because they have a different opinion.. you don't do that, its unprofessional..

    Personal harrsment from Suddoha "What the hell is wrong with you?".. Followed by like from hippocoder and ban..
     
    Last edited: Oct 28, 2017
  21. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Hi, I've banned Ironmax from this thread, so that the discussion can continue in an informed manner. In future please report a user if they aren't acting in a way that keeps a thread healthy.

    Not that I think this thread will be salvaged, but you never know.
     
    Buhlaine, RDeluxe, Havokki and 4 others like this.
  22. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Thanks for saving my time. Not used to argue with people that twist all your words, which he does again and again, even when the quote he comments clearly says something different..
    But well, i saw he had already done the same with people like lordofduct back in the days, by trying to tell them to re-visit basics of coding. :rolleyes:

    Since .NET 4.5 there's also an attribute to aggressively inline methods. It's still being referred to as some kind of 'hint' though, as it'll only be done if it's actually possible. But I could imagine you know about that one already.

    One more thing though, as you've already put such a nice effort in it:
    Try to eliminate some of the branching, more specifically, the lines using the ternary operators in the first place. You surely know about these optimizations, mainly used in highly performant C/C++ and GPU programming.

    So i'd try to sacrifice a few bytes of memory for a lookup instead of doing the branching.
    That's of course heading towards extreme optimization, but you've gone so far already, it's worth a try. :)
     
    Last edited: Oct 28, 2017
  23. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    I made a halfarsed go on trying it, but with the warnings about support of the 4.6 framework being experimental I didn't try to hard to make it work. It doesn't appear to be an option with the normal 2.0 subset.

    I'm tempted, but honestly I feel I've satiated my own curiosity on the topic. I'm not 100% sure I understand what you mean, casting logical operator results to int might be something I'd try in C++ but that's not an option in c#... could possibly tape a bunch of cats together with bit twiddling hacks but I think that's going a bit far...

    Ultimately I didn't want to improve upon the OP's algorithm, because as they said, it's not the point - the point was you'd perhaps expect somewhat better than what you seem to get (unsafe test wasn't intended so much to see how faster it would go but to try and understand if the bottleneck was reasonable, bounds checking being something I think we can respect some penalty for); to that end if I do try anything more it will possibly involve reading a tutorial to see if I can figure out how to call native code from a DLL to compare against a c++ version.
     
    Suddoha likes this.
  24. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    The main idea was to avoid branching (the lines with ternary operators) in the tight loop. Given certain circumstances, such as dynamically calculated values, the path to take (from the perspective of the program flow) is not a linear one. If you had a lookup-buffer of size that matches the range of values that 'n' can take, you can use 'n' as an index to look-up a corresponding value.
    Now this is only useful if the operation to avoid is worth the sacrifice and only if the buffer is of a reasonable size for the situation at hand.

    I know, but you just seemed to have such a good run. You usually do not expect someone's going to try from scratch, and I honestly did not expect you'd enter the world of unsafe code for that - which i appreciated even more. It's already impressive how far you've pushed it though, during all the iterative improvements, and I understand you don't wanna put much more time and effort into it.
     
    Last edited: Oct 28, 2017
  25. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    I'm not sure branching is a significant cost. The following (I went with bit twiddling) seems slower at around 265-ish fps

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public unsafe struct foo {
    4.     public fixed byte World[65536];
    5.     public fixed byte World2[65536];
    6. }
    7.  
    8. public unsafe class LifeBehaviour : MonoBehaviour {
    9.     const int width  = 256;
    10.     const int height = 256;
    11.     foo foo;
    12.     private byte[] texArray = new byte[65536];
    13.     private bool swapBuff = false;
    14.  
    15.     void Start () {
    16.         fixed (byte* ptr = foo.World2) {
    17.                 for (int y=0; y<height; ++y) {
    18.                 for (int x = 0; x < width; ++x) {
    19.                     var s = Random.Range(0, 2) == 0 ? (byte)255 : (byte)0;
    20.                     ptr[y*width + x] = (byte)(s & (byte)1);
    21.                     texArray[y*width + x] = s;
    22.                 }
    23.             }
    24.         }
    25.     }
    26.  
    27.     void Update() {
    28.         fixed (byte* ptr = foo.World)
    29.         fixed (byte* ptr2 = foo.World2)
    30.         {
    31.             const int h = height - 1;
    32.             const int w = width - 1;
    33.             int n;
    34.             byte* p = ptr2, p2 = ptr;
    35.             int s;
    36.             if (swapBuff)
    37.             {
    38.                 p = ptr;
    39.                 p2 = ptr2;
    40.             }
    41.  
    42.             p += width;
    43.  
    44.             for (int y = 1, XY = width; y < h; ++y, p += 2, XY += 2)
    45.             {
    46.                 for (int x = 1; x < w; ++x, ++p, ++XY)
    47.                 {
    48.                     p -= width;
    49.                     n = *(p - 1) + *(p) + *(p + 1);
    50.                     p += width + width;
    51.                     n += *(p - 1) + *(p) + *(p + 1);
    52.                     p -= width;
    53.                     n += *(p - 1) + *(p + 1);
    54.  
    55.                     s = (8 >> n) & 1;
    56.                     s |= (8 >> (n + *(p))) & 1;
    57.                     p2[XY] = (byte)s;
    58.                     texArray[XY] = (byte)(~(s - 1));
    59.                 }
    60.             }
    61.             //TODO: handle borders here!
    62.         }
    63.  
    64.         var tex = new Texture2D(width, height, TextureFormat.R8, false, true) { filterMode = FilterMode.Point };
    65.         tex.LoadRawTextureData(texArray);
    66.         tex.Apply(false, true);
    67.         GetComponent<Renderer>().sharedMaterial.mainTexture = tex;
    68.         swapBuff = !swapBuff;
    69.     }
    70. }
    EDIT: shaved off an instruction or so from the bit twiddles
     
    Last edited: Oct 28, 2017
    Suddoha likes this.
  26. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I'm not sure either, at least when it comes to CPU-bound stuff. It used to be (or is still a thing) in GPU programs (for instance shaders), but well, it's a different chip architecture for different purposes.

    Long story short, i've never tried, it's just an idea, maybe I should fiddle around a bit but honestly, looks like you're more into that. ;)
     
  27. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,660
    I'm surprised that nobody's done this yet:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Rendering;
    4.  
    5. public class SimDriver : MonoBehaviour
    6. {
    7.     public Texture2D InitialState;
    8.     public ComputeShader Computer;
    9.  
    10.     private Renderer _renderer;
    11.     private RenderTexture _fromTex;
    12.     private RenderTexture _toTex;
    13.     private int _kernelIndex;
    14.    
    15.     void Start ()
    16.     {
    17.         if (!SystemInfo.supportsComputeShaders)
    18.         {
    19.             Debug.LogError("Compute shaders not supported on this platform");
    20.             enabled = false;
    21.             return;
    22.         }
    23.        
    24.         _renderer = GetComponent<Renderer>();
    25.  
    26.         var desc = new RenderTextureDescriptor
    27.         {
    28.             enableRandomWrite = true,
    29.             width = InitialState.width,
    30.             height = InitialState.height,
    31.             volumeDepth = 1,
    32.             msaaSamples = 1,
    33.             dimension = TextureDimension.Tex2D,
    34.             colorFormat = RenderTextureFormat.R8
    35.         };
    36.  
    37.         _fromTex = new RenderTexture(desc) {name = "Tex1"};
    38.         _fromTex.Create();
    39.         _toTex = new RenderTexture(desc) {name = "Tex2"};
    40.         _toTex.Create();
    41.        
    42.         Graphics.Blit(InitialState, _fromTex);
    43.  
    44.         _kernelIndex = Computer.FindKernel("CSMain");
    45.     }
    46.    
    47.     void Update ()
    48.     {
    49.         _renderer.material.mainTexture = _fromTex;
    50.         _toTex.DiscardContents();
    51.        
    52.         Computer.SetTexture(_kernelIndex, "FromTex", _fromTex);
    53.         Computer.SetTexture(_kernelIndex, "ToTex", _toTex);
    54.         Computer.Dispatch(_kernelIndex, _fromTex.width, _fromTex.height, 1);
    55.  
    56.         var temp = _toTex;
    57.         _toTex = _fromTex;
    58.         _fromTex = temp;
    59.     }
    60. }
    61.  
    Code (CSharp):
    1. #pragma kernel CSMain
    2.  
    3. Texture2D<float> FromTex;
    4. RWTexture2D<float> ToTex;
    5.  
    6. bool State(uint2 coords, uint2 offset)
    7. {
    8.     uint width, height;
    9.     FromTex.GetDimensions(width, height);
    10.  
    11.     coords.x = (coords.x + width + offset.x) % width;
    12.     coords.y = (coords.y + height + offset.y) % height;
    13.    
    14.     return FromTex[coords] > 0.5 ? true : false;
    15. }
    16.  
    17. [numthreads(1,1,1)]
    18. void CSMain (uint3 id : SV_DispatchThreadID)
    19. {
    20.     bool alive = FromTex[id.xy] > 0.5 ? true : false;
    21.  
    22.     int neighbours = 0;
    23.     neighbours += State(id.xy, uint2(-1, -1)) ? 1 : 0;
    24.     neighbours += State(id.xy, uint2(-1,  0)) ? 1 : 0;
    25.     neighbours += State(id.xy, uint2(-1,  1)) ? 1 : 0;
    26.     neighbours += State(id.xy, uint2( 0, -1)) ? 1 : 0;
    27.     neighbours += State(id.xy, uint2( 0,  1)) ? 1 : 0;
    28.     neighbours += State(id.xy, uint2( 1, -1)) ? 1 : 0;
    29.     neighbours += State(id.xy, uint2( 1,  0)) ? 1 : 0;
    30.     neighbours += State(id.xy, uint2( 1,  1)) ? 1 : 0;
    31.  
    32.     bool newAlive = alive ? (neighbours >= 2 && neighbours <= 3) : (neighbours == 3);
    33.  
    34.     ToTex[id.xy] = newAlive ? 1 : 0;
    35. }
    Runs a 256x256 simulation at an average of about 0.5ms/frame, or 2000 FPS.
     
    Lu4e, DwinTeimlon, KelsoMRK and 5 others like this.
  28. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Probably because compute shaders are really poorly documented! It's a really good solution, though.
     
  29. LogicVision

    LogicVision

    Joined:
    Oct 28, 2017
    Posts:
    4
    Sorry but isn't this off topic? I am curious how C# speed can be done to increase fps in games.
     
  30. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,660
    If the topic is "how to micro-optimise C#," then I guess it is off-topic, but the topic does not make sense - it is not meaningful to restrict optimisation to one part of the system like that.

    Even if you do want to ignore the rest of the device beyond the CPU for some reason... it's a good idea to learn compute-shader-style solutions to this problem anyway, because that's the best way to be prepared for the new jobsystem.
     
  31. LogicVision

    LogicVision

    Joined:
    Oct 28, 2017
    Posts:
    4
    Right, so what in percentage do you think the C# scripts have in play with the FPS render? Since the topic was about speed and not optimization c# vs c++. I understand that the topic doesn't make sense but still.
     
    Ironmax likes this.
  32. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,660
    It's very difficult to give a general answer to that question, but I'll try:

    Most of the work that most games do does not take place in C#. Things like animation, culling, and render command generation - these things are all inside the engine's native code, where we have jobified them and SIMDed them and continue to look for ways to make them faster with each release. For these things the C# code is really just operating the control panel for the heavy machinery; you can optimise that code to pull the levers faster, but it's not going to make a big difference.

    However, some games do have some portions that are not like this: some system that is doing heavy computation itself, that is not in native engine code. A cellular automata is a good example of this; also things like custom particle system behaviour, or something like the traffic simulation in Cities: Skylines. In general, if such things can be pushed to the GPU that is often a good option - the GPU is good at computing large parallel simulations - but if they can't, then C# optimisation can help.
     
    katoun likes this.
  33. LogicVision

    LogicVision

    Joined:
    Oct 28, 2017
    Posts:
    4
    That made it allot more clear for me. Then the question will be, is it the native code that drives the CPU functionality or the C# code? Like is every C# code you write directly impacting native code after bytecode objects conversion? Or does Unity have a separated IL for CPU related codes?
     
  34. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Seems like LogicVision and Ironmax are the same ip address.
     
    Baste likes this.
  35. katoun

    katoun

    Joined:
    Dec 26, 2012
    Posts:
    91
    1. You DO have to worry about the performance from your scripts. If you're saying that, you make me think you have never delivered a big project. I have. I also have been working in the industry for 12 years with various technologies, programming and scripting languages and different sized projects.
    2.You say C++ drives the speed of your C# code. Well, if that speed is for some reason horrendous, what are you going to do? Modify the C++ code? No, you can not, because that is generated code from the IL2CPP compiler. Your only solution is to optimize the performance through your C# code.
    Reading your comments, it seems you got some concepts right, and others really wrong. On top of that, You exaggerated this topic by making it personally, when someone else had a different opinion than yourself.
    P.S. In the end is not this simple, this black and white as you are trying so hard to make us think it is. Optimizations come from all parts of the game engine and the game code.
     
    Last edited: Oct 30, 2017