Search Unity

Arithmetic instruction limit of 512 exceeded

Discussion in 'Shaders' started by milkytreat, Aug 21, 2010.

  1. milkytreat

    milkytreat

    Joined:
    Jan 15, 2007
    Posts:
    267
    Hey there,

    Im converting GLSL to CG for use in Unity and i've got a loop that calls a function...

    If I halve my loop counter it works perfectly fine, but if i leave at what it was in GLSL it fails.

    Not really sure what the difference is, i mean it runs perfectly fine on my GPU. Maybe Shaderlab/CG is unrolling my loops?

    Any Ideas? Right now im only doing #pragma target 3.0
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Please can you post the shader code (both versions).
     
  3. milkytreat

    milkytreat

    Joined:
    Jan 15, 2007
    Posts:
    267
    Sure I've sent you a private message with the shaders
     
  4. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Yes, Cg most often unrolls the loops. What are you doing that you hit 512 instructions?
     
  5. milkytreat

    milkytreat

    Joined:
    Jan 15, 2007
    Posts:
    267
    texture deformations mostly, most of the stuff is pretty math heavy and later i hope to raymarch distance fields- which will be worse/better :)

    I didn't think cg would be so limiting as opposed to glsl? Is this something that can be fixed?
     
  6. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    Same here, and i read on wiki that SM3 was 65500 instructions!
     
  7. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    As I recall, there is some ARB directive that lets you increase the number of instructions you can use without rising the shader model dependency. Search around...
     
  8. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
  9. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Did you get #pragma profileoption NumMathInstructionSlots=65535 to work? If so, how? It doesn't work for me, although my video card should be able to handle it.
     
  10. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    it works very nicely, perhaps go for 2048 4096 8192 and see. please say if there is an earlier limit.
    #pragma profileoption NumInstructionSlots=65534
    #pragma profileoption NumMathInstructionSlots=65534

    what error message are you getting?
    It's a shader model 3 instruction so #pragma target 3,

    I put it towards the top of the #pragma, sometimes order has an effect on it.
     
    Last edited: Oct 24, 2013
  11. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214

    It tells me that the arithmetic instruction limit of 512 is exceeded; and sometimes it says that it doesn't recognize NumMathInstructionSlots (altho it does recognize NumInstructionSlots and will respond to it). I've tried every combination I can think of, in terms of the number of slots (1024, 2048 etc), and the order for the #pragma instructions. Nothing works. I'm using #pragma target 3.0, so that's not the problem.
     
  12. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    update drivers... latest are ok here. graphics card version?

    "it does recognize NumInstructionSlots and will respond to it"... that should increase limit abit if it responds. how do you know it responds?

    Re: I hit the limit of instruction slots 512 when I was writing fragment code so I put in the NumInstructionSlots to 2048 and I was able to code more maths and then I hit another error message saying- number arithmetic instruction slots exceeded , so I also added NumMathInstructionSlots=2048 and the code ran fine again with even more maths, and so I put them both up to 65000 which is the theoretical limit I think for my card, and it runs fine, except that unity froze on compiling when I tried a code combination that must have been about 30000 instructions.
     
    Last edited: Oct 25, 2013
  13. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Because if I set it to a very low number, I get a new error saying that the shader exceeds the total instruction limit, not just the math instruction limit. So it's clearly responding to NumInstructionSlots, although it doesn't seem to check for an uppermost limit, since I can set it to eight million (for example) and it has no problem with that for some reason. But it specifically says it doesn't recognize NumMathInstructionSlots.
    I have an Intel Graphics Media Accelerator 4500M, which is supposed to have Shader Model 4.0.
    Do I need Unity 4.0 ? Right now I'm using v. 3.4.

    A shader with 30,000 instructions is my great dream.... ;) Plus, shader processing units that are at least as powerful as a 286 CPU....
     
    Last edited: Oct 25, 2013
  14. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    if the error is just on one graphics card, i.e. one from 2009, and another pc can run it, then it's the hardware that can't cope... you can always attempt to do it on a dx11 graphics card, sm5 can have 10000'ds of instructions. it's not a unity error it sounds like a CG compilation error on a different compiler of some sort it's some kind of specific cg compiler engine! general infos and similar bugs that should be on google.
     
  15. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    I haven't tried it on another machine. The Cg compiler I'm using is the one built into Unity.
     
  16. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    its a third party/seperate compiler written by nvidia that game engines integrate to their games, but they just use the standard nvidia compiler all of them for cg code. probably post to stack exchange. http://http.developer.nvidia.com/Cg/arbfp1.html

    are you hiding the fact you have an ancient gfx card because you didnt say which yet, you ignored the question, and it's the pivotal hardware issue.
     
    Last edited: Oct 26, 2013
  17. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    try it on a different shader to know it's your hardware-
    http://pastebin.com/n5cPucSN
    you can use that code and then make a loop of 1000 instructions in it, it works with that code.
     
  18. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    In my post yesterday at 1:34pm, I already said what my graphics card is : it's an Intel Graphics Media Accelerator 4500M, which is supposed to have Shader Model 4.0 and hence it should work. I freely admit it's five years old and is made out of wooden cogwheels powered by gerbils running in a treadwheel; but it should have the capability to have more than 512 instruction slots. Here are the specs: http://www.notebookcheck.net/Intel-Graphics-Media-Accelerator-4500MHD-GMA-X4500MHD.9883.0.html

    I made a loop out of 95% of the vertex program with a count of 1000, then 4096, and it compiled both even without needing to increase the math instructions.... although the compiled shader assembly code shows that it isn't unrolling the loop (the entire vertex program was only 44 instructions in the opengl assembly), nor is it generating a loop command in assembly; probably because each iteration of the loop doesn't actually change anything since the counter is never factored into the calculations (the result after 4096 iterations would be the same as after one iteration). So I changed the calculations to use the counter, and it only added one instruction to the opengl assembly. So I added #pragma target 3.0 and it seems to have added a loop instruction to some of the assembly code.
    Is there any way to write it directly in assembly, so I don't have to guess what the compiler is going to do with the code? I spend a lot of my time fighting with the compiler, and the compiler always wins.
     
    Last edited: Oct 26, 2013
  19. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    test number instructions I meant to make a loop that += .001 1000 times or just copy and paste some instruction line 500 times!

    your graphics card does 17 FPS in World of Warcraft 1280 x 720... try and get another laptop with a dedicated graphics card, you can probably find one with a faulty hard drive from someone local. You would really be wasting your time using assembler language, sometimes it's really time to move on and get another laptop. for comparison, the x1400 mobile graphics from 2005 was at least 10 times faster.
     
  20. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Ok, I put the following code in the fragment shader:

    for (int bob=0;bob<1000;bob++)
    {
    bob+= .001;
    }

    And the compiler says: 'profile does not support "for" statements and "for" could not be unrolled'... and exactly the same thing happens when I change the loop to only run for one iteration. The compiler has accepted "for" statements in the past, however. And I'm using "#pragma target 3.0"

    If I had the money, I'd gladly upgrade to a real computer. But in the meantime, I have to make use of the one I have.
     
  21. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    Last edited: Oct 27, 2013
  22. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Thank you for the suggestion. I'll look on Ebay for some good deals.
     
  23. reefwirrax

    reefwirrax

    Joined:
    Sep 20, 2013
    Posts:
    137
    #pragma profileoption NumTemps=36 this didnt work arrrggg. seriously get a dx11 graphics card, anything, like a 430 even!!! you get compute shaders, etc. they are actually quite easy to program.