Archived

This topic is now archived and is closed to further replies.

Succinct

Borland automatically adds exception code!?

Recommended Posts

Hey, guys. I''m making some rendering tools using Borland C++ builder (4.0, Professional ed.). I figure, it''s just tools, so I can use RAD. Well, here''s the thing: I''m using my own custom Bitmap container class, and the class is written to be very thin/speedy. Under MSVC++ it runs pretty good, but w/ Borland it is a little slower. I stepped through the asm stuff the compiler is spitting out and found that it''s generating exception handling prologue/epilogue code for each and every function! The stuff I''m doing only needs exceptions in 1 place: the actual call to allocate memory for the bitmap. Since it''s unnecessarily in every function, including the void constructor for my Pixel class, I think it probably has something to do with it... The pixel class''s void constructor is called for each and every pixel created, and ,even though it is inline, having that extra exception handling code that Borland is generating in each call causes an extra 1024x768 blocks of code to be run through if I was to allocate an image of say, a screen rip. That''s a little too much processing overhead, I''d say. Now, another thing I realize is that in order to step through code, the code must be built in debug mode. Maybe Borland throws them in no matter what for debugging, so these calls may not be in the release builds. Well, that says that my code is just pokey, but my argument against this is that there is not much of a speed difference between debug mode and release mode builds, at least not enough to say that these lines of code are coming out. Secondly, you can''t disable exceptions for the entire app, because Borland''s native stuff needs it enabled. The only specs I can find about disabling exceptions on a per unit basis is the -x pragma directive. Thing is, it says: "If this option is disabled (-x-) and you attempt to use exception handling routines in your code, the compiler generates error messages during compilation." Which does not say that it won''t put exception handling code in, just that it will yell at you if you try to so that, if you are planning on porting your code to another platform where exceptions are handled differently, this section of code won''t be a problem. Does anyone know how to stop borland from inserting these exception prologue/epilogue blocks? Thank you for your bandwidth. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~Succinct Demos Online~ I am a software engineer who writes poetic code!

Share this post


Link to post
Share on other sites
Try giving your functions empty throw specifications, to tell the compiler that the function does not and throw any exceptions. This might allow it to remove the exception handling code altogether, or at least reduce it in size. In case you''re not familiar with throw specifications, they look like this:

  
// Throws nothing

void SomeFunction(int param) throw ()
{}

// Can throw ints only

void SomeOtherFunction(int param) throw (int)
{}

// Can throws absolutely anything

void AnotherFunction(int param) throw (...)
{}


I don''t know if Borland supports or uses throw specifications, but it''s worth a try.

(Not that I''d use a Pixel class for anything What do you need such fine-grained objects for?)

Share this post


Link to post
Share on other sites
I think the problem lays with "pixel class"; WTF are you thinking!? Seriously though, what''s the pixel class do? Without the exception baggage, that''s still probably way too much OOP.

P.S. I imagine Delphi does the same thing and we''re currently optimizing a section of our Delphi code where I work. I''ll check into this in detail on Monday.

Share this post


Link to post
Share on other sites
Even though you can''t step through code in a release build, you can still see the assembly. Check the docs for the compiler param (or there''s probably something in the options dialog) to generate an assembly listing. You can search through the listing for exception code.

Good luck.

Share this post


Link to post
Share on other sites
I made a pixel class before... kind of.

it was actually called a ''bitmask'' class, which handled all types of pixel conversions (literally, any ARGB format could be represented and converted to another). Quite helpful.

Share this post


Link to post
Share on other sites
Kylotan:
Sounds like it''s worth a try.
BTW, yes, I know about exception specifiations .


Mag:
Hey, I need that Pixel class, dangit!

Seriously, though, the work I do needs a lot of software rendering stuff, so I use the Pixel class to 1) abstract the need of tracking 3 unsigned chars (or any other representation thereof) and 2) to overload operators so the code looks right when I''m doing my filtering math.

What''s wrong w/ using a pixel class? I have it packed, no destructor, the void destructor does nothing, and it''s all inline. If I get rid of the exception handling code, whats the difference between a pixel class and a pixel struct?

I just got bored with writing 3 lines of code (instead of a for loop w/ 3 iterations), each line having the same code, just working on a different color byte.

I''ll be looking into this more on Monday, too, so we can keep each other posted. And yes, I agree, Delphi probably does the same things.

Qoy:
Yes, there is an option for this. I''ve been reluctant to try it, though, because w/ Borland C++ Builder, compiling all of the library code it uses brings the line count to well over a million. I would be hard pressed to search through it to find my measly 4500. I guess a search would work well here. Thanks for the push.

Mithrandir:
Yes, I forgot about that, too: 3) because it''s a template class, I can use it to convert any RGB(A) format, be it floats, doubles, ints, unsigned chars, or whatever.

Thanks guys!

Share this post


Link to post
Share on other sites
I don''t think anyone would recommend a pixel struct either I think I would abstract it a bit further up. Eg. making classes such as Bitmap8bit, Bitmap16bit, etc. I know this might seem to be redundant, but they can still share functions where the pixel size is irrelevant, either through functions in a common base class, or through templatizing certain functions.

And people who don''t use C++ manage to use some simple macros to eliminate the chore of manipulating 3 chars each time. You could use macros or inline functions.

Share this post


Link to post
Share on other sites
To help with your search if you choose to look through the assembly listing: there''s probably an option to include the C/C++ code as assembly comments in the listing file. You could just use whatever text editor you use to view the listing to search for whatever C++ code is in the function you want to check out..

Good luck.

Share this post


Link to post
Share on other sites
Well, looking through the asm produced, it doesn''t look like there is any extra overhead by using my Pixel class. Maybe a dereference per operation that I''m not picking up though...

At least, that''s the only argument I can see against it. Anyone have real evidence as to why I shouldn''t use a Pixel class?

-- Succinct

Share this post


Link to post
Share on other sites
This whole thread is an example of why most people wouldn''t use a pixel class. You have more function calls, which by their nature is going to slow things down. Compilers also have to do more work for a given algorithm, which makes it less likely they''re going to successfully optimise it. You have issues such as structure size to take into account (a ''class Pixel { short colour; }; is not necessarily going to be 2 bytes in size by default). You have more functions that need to be able to possibly handle exceptions.

All these things, you can probably get around, with a lot of work spent inlining, pragma packing, etc. And what are you gaining as a result? Do your pixels have any virtual functions? If they do, is there any point? Do you have more than 1 pixel type in a given image? And that would just generate extra vtable space and so on. It just seems like a lot of effort to create an object that doesn''t serve much of a useful purpose. Objects buy you design benefits at a cost of performance. 99% of the time you gain more than you lose, but when the granularity is too fine, there''s rarely any point.

Share this post


Link to post
Share on other sites
Mag:
Ahhh, that makes sense, as a lot of the extra code is just adding some local space on the stack and filling it. Cool stuff, man, thanks!

Kylotan:
From what I''ve read so far in this thread hasn''t given me any concrete arguments against using my pixel class.
Yes, I inline every function, because there are places any one of them could be called many times, but that''s an extra word of code/definition.
There''s not much room for compiler optimization, as the code is close to asm anyway. All of the asm I see being spit out is line for line the same thought process I had when writing the c++ code. To use the SIMD instructions, I would have to reorganize my code anyway. The only possible optimization I can see (though my Intel asm vocabulary basically stops after the i486), would be using MMX, but those need to be hand coded anyway, to my knowledge.

They are packed so that a 24-bit TPixel class uses 3 bytes, and there is no exception handling needed for any of the functions. This only takes 4 lines to do: 2 to set it up before the class and 2 to clean it up after.

There are no virtual functions, as the classes weren''t meant to be in an inheritance hirearchy. If that stack checking swtich works, and I think it should, there will be absolutely no extra overhead on top of manually manipulating 3 bytes seperately, and that''s considering you are only working on 24 bits. To encapsulate all current formats would require that you write individual image classes for each type of pixel format, for each type of image encoding. Using my pixel class, I only have to make a few specializations, and I can use the TPixel class for any image, accepting the type of component format as a template parameter.

Remember, I am doing a lot of software image manipulation, and the granularity here is necessary because when I''m writing my tri-linear interpolated image morphing code, I would rather see math performed on entire pixel objects with out worrying about the individual components. My image class has to be general enough to encapsulate any RGB(A) format, from using monochrome bits to GLfloats, and conversion is necessary in some cases, too. Based on all of the presented arguments, yours, mine, and all others here, I don''t think I''m all that crazy for using a pixel class.

Thank you for your interest, though, Kylotan.

Share this post


Link to post
Share on other sites
Succinct. There is no reason not to use your pixel class.

C++ compilers are no more code bloater(asside from your exception problems with borland).

A small completly inlined class will be as fast as macros in release mode. In debug, you don''t care!

I have a ray tracer/radiosity that used small basic class for coloring (RGB, RGBA, LUMINANCE) and I build images from it

template
class Image
{

array of COLORTYPE;
}

Image supports operation like *, + , -. The implementation is really simple because each basic class also have those operations.

A friend of mine did the same thing for an RGB image but with macros.

Speed difference to do image operations on an 850Mhz?( in release mode of course)

0 - none - (somethimes his was a little faster, somethimes mine was a little faster)

the good thing is my code is easier to read and easy to modify and extend.

Oh well, I feel sorry for the people who looks at the Quake source and thinks it is the greatest thing on earth and it is how they should write their code.











Share this post


Link to post
Share on other sites
Mag:
It''s the command line option k.
Thing is, though the help docs say:
"Other options can be changed anywhere. The following options will only affect the compiler if they get changed between functions or object declarations:"
and include -k in there, putting
  #pragma option -k-  
in before my functions or before any objects, even at the top of the file, does nothing...

*makes a realization*
Disabling the stack frames option explicitily under the project options dialog does not remove it... Maybe it''s not the stack frames, mag...

Oh well, more research is necessary...

Share this post


Link to post
Share on other sites