|
Unless you have a good, compelling argument otherwise (and there are a few), you should prefer to pass structs as parameters. If its small (e.g. something like a struct timeval ), and you don't need to modify the members, its OK to pass by value. If its large, then pass by reference (pointer). If you're not going to modify the struct in the function then you should mark the reference as const.
struct small_obj {
char description[16];
int count;
};
struct large_obj {
char text[1024][1024];
double factor[1024][1024];
};
void f1(small_obj arg);
void f2(small_obj* arg);
void f3(const small_obj *arg);
void f4(small_obj& arg);
void f5(const small_obj& arg);
void f6(large_obj arg);
The problem with global values, especially global values that are not local to a single file (e.g. declared as static), is it becomes increasingly more difficult to reason about where the variable gets modified. Given a function say print_item(void) you might not expect your global Item to get modified, but print_item() calls foo(void), which calls bar(void) which calls frobnicate(void), which modifies Item. If you are trying to trace down a bug, trying to see where Item gets modified can be difficult. On the other hand, calling print_item(const Item&), you can be (more or less) sure that Item doesn't get modified during the lifetime of print_item() (more or less because print_item() could be nasty and cast away constness, but that's an evil for another tale). Alternatively, you might have print_item(Item foo), which gets a local copy of Item, so the caller knows that whatever changes print_item might make to its copy, the callers Item remains unchanged.
Keep Calm and Carry On
|
|
|
|
|
Thanks, you may have answered my other problem.
( I'll posting it soon.)
At this point I use struct sort-off attached to a class.
Not static.
I am saying sort-off because the main code is OpenGL and it does not work well in C++ class.
I do not foresee any other code to modify it.
But for learning experience I'll go with passing the struct via pointer to the function which is also "passed" as parameter to another function.
Pretty convoluted , mostly because OpenGL "pipe" architecture.
But so far it id working as expected.
|
|
|
|
|
Is there a listing for the cost of math functions? (how much cpu time math functions take). i.e sin(), asin(), sqrt() ?
|
|
|
|
|
No - it depends on the compiler, the library, the OS, the processor, the system loading, the ... you get the idea.
You want to find out? Write code to execute the same function for a huge range of values and run it many, many times. Time that, and average out the run time by the number of sin operations. Ruin this a dozen times, and average out the values.
Then take out the "payload sin call" and repeat the tests. The difference should be the execution time of the sin operation.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks, if we talk about functions ( and other math operations, additions, substractions, multiplication, division) with a wide margin cost difference can`t you make a ranking of them.
I want to make a raytracer and I`m just bracing myself against making foolish things/mistakes.
|
|
|
|
|
That is more generally the compiler/optimizer responsibility. You are better off leaving that sort of thing to the end.
I can highly recommend learning the whole process on a simple software renderer
You will be hard pressed to find a better start point than this link because it's really a couple of simple files.
GitHub - ssloy/tinyrenderer: A brief computer graphics / rendering course[^]
He has a nice easy to follow sequence from raycaster to the renderer being the most complex but on 500 lines of code.
Home · ssloy/tinyrenderer Wiki · GitHub[^]
In vino veritas
modified 17-Apr-20 13:10pm.
|
|
|
|
|
hey leon de boer
Quote: I can highly recommend learning the whole process on a simple software renderer
I`m familiar to DirectX, I find raytracing intriguing, I want to give it a try.
|
|
|
|
|
Write the code AND THEN refactor (based on analysis of the actual code.)
|
|
|
|
|
That is the agile spirit! Do something quick and dirty, AND THEN discover that it was rather silly...
I admire fearless_ for wanting to do a prestudy do determine the cost of various alternatives, to rule out the obviously invalid ones. Then he dan make a small testbed for the candidates, and from that choose the one looking most promising, and then start coding.
I know very well that agile principles demand that you start your "int main(int argc, char *argv[]) {return 0;}" an make sure it compiles, as a prerequisite before you start asking what the problem is, that you are on your way to solving that problem that hasn't even been ideitified yet. I am so old styel that I prefer to tanke a look at both problem definition and tools available before I race along in that "implementation before problem understanding" race. I know that I am a silly old fool, thinkoing that way
|
|
|
|
|
This has NOTHING to do with agile. This is a tried and true principle of software engineering; first solve the problem and then refactor and optimize.
|
|
|
|
|
I'm sorry for stepping on your toes.
Obiviously, "Code first, refactor later" is not at all related to agile coding.
|
|
|
|
|
I suppose you might find benchmarks on the web. At least you may perform some tests yourself.
|
|
|
|
|
Are you really sure that it matters?
It might, in some very special applications. But most developers tend to overestimate the relative fraction of "calculation" in their code. The data handling often takes up a far larger fraction of the processing time that they thought.
Also: How often do you have a real choice? If your algorithm calls for a sin(), is there anything you can do to avoid it? Not very often! If you do have a choice, implementations vary so much that you should set up a simple test bed and try it out.
One thing I have learnt through simple timing tests: On any CPU architected the last 30 years, timing individual instructions is more or less meaningless. Prefetching and pipelining and speculative execution and whathaveyou can make addition of a simple instruction (e.g. arithmetic) almost unnoticable on the execution time of a tight loop. So don't worry about those.
What really matters is not the execution time of the trig functions (and other mathematiclly complex operations) in themselves, but the number of times you call them. I never programmed any ray tracing myself, but I would not be surprised if there is a lot to be saved in caching, reusse and clever prioritizing to make the most visible effects appear first, details only if you have got the time to do it, before the next update.
|
|
|
|
|
There are lists of the timing properties (not "the time it takes", it's more complicated and you must at least distinguish latency and throughput) of individual instructions for particular CPUs, for example
sqrt more or less corresponds to the similarly named instructions (fsqrt or sqrtsd whichever is appropriate), except it may have some overhead in order to test for negative input and set errno . sin and cos normally don't correspond to fsin and fcos , along with other trig functions they're normally implemented as some non-trivial function of many instructions. The exact implementation varies based on which math library you use. About the only way to get their timing data is to test them yourself.
A popular approach for fast ray-tracers is to use SIMD processing through ray-packet tracing, though there are other ways to incorporate SIMD. Intel has an introduction to ray-packet tracing, it's showing its age with the 128bit SIMD but it could be extended to 256bit. There is a lot of literature about SIMD in ray tracing, and it's probably useful to read some of it in advance because once you're written a non-SIMD ray tracer it becomes harder to hack SIMD in, than it would have been to base the design around it in the first place.
|
|
|
|
|
thanks for positive feedback, there`s plenty to learn
|
|
|
|
|
VS2008, Windows Embedded Compact 7, mfc dialog application that is 4 years old. It's been working fine. Today I've been making improvements, tracking down some long standing issues. Up until this afternoon, I could pretty much debug where I wanted but then suddenly my UI loop stalled in the OnInitDialog. Stepping through, I came to a couple of LoadBitmap calls that I use to load images from the embedded resources. The first call does not error out, it just never comes back from the LoadBitmap call.
This smells like some weird elephanting debris from VS2008. Some references suggest memory issues on the target device, etc, but it's been rebooted, this is a lightweight app... and doesn't use much memory.
Anyone seen LoadBitmap stall like this?
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
Did you tried to load another bitmap, something small in order to find out where is the problem ?
|
|
|
|
|
I actually did... there are only three bitmaps in the project. I added some code:
CBitmap myBitmap;
myBitmap.LoadBitmap(IDB_STOP);
it never returns from the LoadBitmap... very odd. The bitmaps are not large (200x200?), and the really weird part, again, is that this code has been working for many years.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
I would try a little workaround: use CImage instead of CBitmap ... at least you will know where is the problem, or, you will solve the issue .... However, CBitmap is reliable ... I don't think that code from above is causing the problem ... the cause must be in else where.
|
|
|
|
|
Check you have not got a clash on IDB_STOP and you actually have the resource of that ID in the project. All you need is a corrupt resource file and it can't connect the dots.
In vino veritas
|
|
|
|
|
That's why I told him to try to load another bitmap resource just for testing ...
|
|
|
|
|
good idea, "use the source luke"... looking now - yeah, this looks good. I would expect the loadbitmap operation would just fail and not hang. The resource is built into the exe. Trying the load image... I love you Microsoft.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
So, tried the CImage -> LoadImage approach - no go. Hangs in that call as well. I'm going to sell my house and buy a sailboat....
elephanting code - okay, I figured out why the call hangs. This application is my application loader code in an embedded target. We have two types of upgrades - one with and one without an operating system. So, one thing I need to do is dismount and remount the device partitions (this is Windows Embedded Compact 7), so I can modify OS files. This typically is not a concern, since by the time we're running, everything is running out of ram. Once complete, the device reboots. No harm.
Now I don't know how LoadBitmap is implemented, but it appears that it reads the resource information from the exe file and not what is in RAM. Egg on my face since I missed the #define change. I still argue that LoadBitmap should return gracefully with an error code. Heh it's mfc, filed under "don't do that."
Appreciate all the suggestions.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
I agree LoadBitmap should not fail like that but it is specified the resources are never lifted into RAM. They are tagged in special sections in the file and are excluded from the normal executable load to avoid using memory when not required. Remember a file may contain many resources for different resolutions, languages and the like and much would then be redundant duplicates hogging memory.
In vino veritas
|
|
|
|
|
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|