• Advertisement
Sign in to follow this  

Fastest function execution

This topic is 4786 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using Angelscript to power the fixed function shaders in my system. Obviously, these script functions will be executed at a very critical point of the program, so they need be as fast as possible. What's the best way to prepare and execute 50 different functions? Should I create one context, store 50 function ID's, and simply go through them each and say singleContext->Prepare(functionIDs[index]); singleContext->Execute(); Or, should I create 50 different contexts and call the prepare function in preprocessing? This seems to be a bulky way of doing it.. but, even if it takes more resources, if it's faster it may be worth it. FYI, all the functions are compiled into the same module with different names.

Share this post


Link to post
Share on other sites
Advertisement
I'd never use a scripting language in any part of my rendering pipeline. Are you looking for ways to eat up your fps?

Share this post


Link to post
Share on other sites
Calling Prepare() between each function obviously creates an overhead, but the relative overhead depends on the size of the scripts. If the scripts only has a couple of statements then the relative overhead is quite large, but if the scripts have perhaps 10 or more statements the overhead should be quite small.

Having one context for each of the functions will no doubt be the fastest way, though as you say, it may be a bit cumbersome, and will use a lot more memory. In this case you should take care to adjust the stack size to not be larger than necessary.

In either case you need to take a look at the stack size. Ideally it should have the initial size large enough to run the entire script without having to allocate extra space at runtime. Currently there is no way of dynamically determining the ideal size but I'm planning on introducing this feature.

However I doubt that a scripting library is very suitable for shaders, at least not without JIT compilation. You might want to take a look at something like SoftWire instead.



Share this post


Link to post
Share on other sites
There are stuff that should be scripted and stuff that should be hard-coded. It's up to you how 'flexible' you want your engine to be.

Couldn't you use function pointers and do something like this?

myFunctions[j].Execute();

Share this post


Link to post
Share on other sites
I am only researching different solutions for the application. There is a good chance that most of what I do now won't make it in the real application. I wanted to see what kind of pros and cons this would bring into the system. I don't see why it would be so much slower- it's just like writing a text file configuring a shader and then parsing the text file. It compiles it. But, that's what I am to find out. It would be great to use something like this to make my non-hardware shaders flexible. But if I find that it is too slow, then so be it. But I need to do it myself to see.

Edit- seems that people replied while I was writing. :p thanks for the answers. I'll check it out. As for function pointers, well, in a sense that's what I would do with DLL's. My problem is pulling the shaders outside the system. I'm trying to avoid DLL's, but, if I find those are so much faster, I might have to do it that way. Crap- I though XML files with embedded shader script would be so cool :p

Share this post


Link to post
Share on other sites
Quote:
Original post by okonomiyaki
Crap- I though XML files with embedded shader script would be so cool :p

Yeah, me too. I don't know what API you're using, probably not Direct3D, buf if you are, check out .FX files. Maybe you can make a parser for those....... Hmm.. [grin] [wink]

Share this post


Link to post
Share on other sites
Quote:
Original post by okonomiyaki... it's just like writing a text file configuring a shader and then parsing the text file.


Parsing a text file you do once, usually into a format directly usable in your C++ code. Executing a script every frame is going to be many times slower. Even the fastest scripting language is still significantly slower than the raw c++ code. If you're talking about just defining the shaders in script, so that they are loaded in and used once, thats different, but your post implied to me that you would be calling the scripts each frame.

Share this post


Link to post
Share on other sites
I am using OpenGL, but I use DirectX as well in other applications. I have looked at the FX files, and it looks good, but I don't have the time to write a whole parser myself :p I'm not quite sure what I'm gonna do yet, I'll have to do some refactoring if I go with DLL's, or write my own parser if I go with text files. Either way, it's gonna take some time I guess.

drEvil- you are correct, they would be called every frame. I thought that compiling and preparing in a preprocess step would take away most of the overhead, but I didn't understand scripts well enough. I still want to test it though. thanks.

Share this post


Link to post
Share on other sites
You could have the scripts set up some internal structures that your rendering engine can use to render the fixed function pipeline. This would allow you to use a scripting engine to define the rendering, and still have the speed of direct C++ code when rendering. Example:


// shader script
void Init(shader &sh)
{
sh.renderTexture = true;
sh.texture1 = gfx.GetTexture("Steel");
if( gfx.canDoCubeMapping )
sh.renderCubeMapping = true;
else
sh.renderEnvironmentMapping = true;
}



// C++ app code
CShader *sh = new CShader();
Call Script Shader Init(*sh);

// Rendering
if( sh->renderTexture )
enable texture
if( sh->renderCubeMapping )
enable cube mapping
if( sh->renderEnvironmentMapping )
enable environment mapping


The scripts would serve much the same function as DirectX's effect files, and would also be easy to implement with OpenGL.

You could also allow scripts to animate the shaders, by having the application call an animation script with a shader structure once every frame.

Share this post


Link to post
Share on other sites
Yeah, I thought about that, but it's still not as easy as just letting the scripts do it themselves :p though I think that may be the easiest way. It also kind of makes scripting useless- I might as well just embed the properties straight into XML. I dunno. I'm actually not going to use the fixed function pipeline a whole lot in my program, so I don't have to give it total flexibility. Obviously I can't just totally forego support for it though. thanks for the suggestion.

Quote:
Original post by WitchLord
You could also allow scripts to animate the shaders, by having the application call an animation script with a shader structure once every frame.


But see, how is this different than calling a script to set fixed function states every frame? Wouldn't calling any script every frame produce the same bottleneck?

Share this post


Link to post
Share on other sites
Agreed, for static shaders the difference between using a script and XML is very small in terms of flexibility. For animated shaders the script would be much more flexible.

You wouldn't have a whole lot of animated shaders, so the number of scripts called per frame would be a lot less. Also the animation scripts would only be executed once per frame, not for each mesh. If the animation scripts get too heavy it would also be possible to turn them off, or spread out the calls over several frames, without having to change the rest of the rendering pipeline.

There is no problem calling hundreds of scripts per frame, but there is a problem if you start calling thousands.

Share this post


Link to post
Share on other sites
Ah, see now that you put it that way, I still might use the scripts. I realize that I should have been clearer- I think I was very misunderstood! I would not be calling a script per-mesh, it would only once per-shader, and only fixed function pipeline shaders. The script would simply set up the OpenGL states required to achieve an effect. So, the render process goes like this-

1) Go through all objects, sorting, updating, whatever you do to them. Whenever leaving the object, add it to the render queue.
2) Sort the render queue according to some priorities. Shader is first priority.
3) Start the render queue. Get the first object, setup the shader (would be script), and render it.
4) Go to the next object in queue. Repeat step 3, except if the shader is the same do not set it up.
5) Repeat number 4 until you've finished rendering all objects in queue.

So you see, there would probably only be 15 or 20 scripts executed each frame, as there will probably only be that many fixed function shaders. All of the advanced shaders will be GLSL, including dynamic shaders.

So, that is an appropriate way to use scripts, correct? I definitely want to go ahead and try it out. I'll profile it and get back to you.

edit: I forgot mentioning the per-object parameters. In the script, I would have an object that represent the current mesh, so if you wanted to set the color you would say glColor3f(o->color.r, o->color.g, o->color.b); etc. But, this would not be executed per-mesh, it would be compiled and understood by the engine that would actually run c++ code when rendering each mesh.

edit #2: crap, I just realized that what I'm asking doesn't make any sense. I might as well pre-compile everything into c++ code and not worry about running scripts every frame. What I will do is run the scripts once which will setup the states for an object, and interpret that and execute with c++ each frame. Bah, I don't know if that made sense.

Share this post


Link to post
Share on other sites
What you said with calling the script to set up the OpenGL state could work, though what you said after edit#2 is probably much better.

In my experience it is best to separate the layers as much as possible. The scripting layer should preferably not run during rendering, at most as a step just before rendering each frame. The design will be much cleaner that way, and will be much easier to maintain.

You say that you will only use the scripts for the fixed function shaders. I would suggest you also let the scripts choose what GLSL shader to run, and if the GLSL shader is also an external file the script writer will have complete control.

This would actually be a perfect sample/tutorial to show how to use AngelScript. I will try to find the time to write a simple sample that will show a rotating cube where each side uses a shader controlled by scripts like we mentioned.

In either case I look forward to seeing the result of your experiments.

Regards,
Andreas

Share this post


Link to post
Share on other sites
Great, I'd love to see a sample to see a good design of script and app interaction. Thanks!

I'm not sure what you meant by letting the script choose which GLSL shader to run though. Are you talking about hardware support issues, or simply attaching shaders to objects? So there would be a script that specifies which shader goes with which object?

I already have a fallback system that links shaders with higher level "effects." You actually assign an effect to an object and the system decides the best shader to use on current hardware. You mean to let a script decide which effect to use?

Share this post


Link to post
Share on other sites
Yes, I meant to let the script choose which effect to apply to the object.

The script could also be allowed choose a different effect in case the GLSL isn't supported on the hardware. That would allow the script writer to choose the fallback method. Wether this is what you want or not, I don't know. Basically I'm just throwing ideas at you :)

Share this post


Link to post
Share on other sites
Hi

What you are looking for is run-time intrinsics code or run-time generated code, angelscript is very fast with this, about 2 or 3 times slower than c++

The compilation of the script to assembler code is made at the program start or at a later time if you want (or recompile if the script chaged), and can use the host machine specific capabilities, 3d hardware where aplicable or software, ss2, 3dnow+, and so

So you end executing machine code, instead of bytecode/interpredtedcode

regards

Lioric

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement