Chop All American 6271 Posts user info edit post |
i'm working on a project turning a simulink model into C++ code by hand for use in a micro controller. right now the only way i have to test the code is by streaming data files in and out, as the controller itself is still being developed. as a result, i don't have anyway to see if it can keep up with real time data streaming in (1kHz sample rate).
in terms of processing time, which is faster? (i may add other questions to this thread as they come up)
float var; x=fabs(var);
or
float var; if var<0 { x=var * -1; else x=var; }
[Edited on November 1, 2007 at 5:05 PM. Reason : .]11/1/2007 5:04:44 PM |
clalias All American 1580 Posts user info edit post |
well, I could be wrong here but shouldn't you eschew classes (c++) and really just use straight c code. I mean I know it doesn't apply to your example but do you plan on it? 11/1/2007 5:29:34 PM |
darkone (\/) (;,,,;) (\/) 11610 Posts user info edit post |
No logic is almost always faster than logic. 11/1/2007 5:43:46 PM |
Chop All American 6271 Posts user info edit post |
^^ technically, yes. but i'm not an advanced programmer, so i'm going with what i know. hopefully i'll have the hardware in my hands in a week or so and i'll be able to test as i go. i'm starting off with a pared down version of the model until i know everything is working, then i plan to keep building it up.
just getting the simulink stuff into some reasonable logic is a challenge in and of itself. there's no documention, incorrect tag names, muxed/vectorized signals and bajillion various switches, product, relays all of which are some effective form of if/else conditions.
[Edited on November 1, 2007 at 6:18 PM. Reason : .] 11/1/2007 6:10:15 PM |
BigMan157 no u 103354 Posts user info edit post |
does fabs require the math.h header, or is it a native function?
if it's from the header, open up the math.h file and see how the function works
chances are, doing it the second way will be as fast or faster plus occupy less memory once compiled (since you won't be including the header file)
[Edited on November 1, 2007 at 7:11 PM. Reason : clearer] 11/1/2007 7:10:36 PM |
JaegerNCSU Veteran 245 Posts user info edit post |
fabs(var) is almost always going to be faster than your conditional branching. Modern compilers can look for calls to fabs and optimize them with platform specific code. For example, if you're compiling with MSVC, you can do #pragma intrinsic(fabs) and then use fabs for doubles and fabsf for floats and then the compiler will generate the FABS instruction which is usually only one cycle on a modern x86. Depending on your architecture, you'll definitely want to avoid branching, especially floating point branches like your if var < 0 (this is very important for an in-order processor). You should also help the compiler out by using 0.0f if you want a float. If you're using a compiler without the ability to optimize your fabs calls (really, if you are, get a better compiler), you could do something like this for 32-bit floats:
inline float myfabs(const float f) { int i=((*(int*)&f)&0x7fffffff); return (*(float*)&i); }
But you'll likely introduce two FWAITS with that. But telling MSVC to use the intrinsics implementation of fabs and just calling fabs is as fast as you're going to get with that (one cycle).
This is highly dependent on your architecture and compiler, though, so your mileage may vary.
However, if you're not an advanced programmer with a firm understanding of your architecture you're not going to be able to make your code perform as fast as possible. My advice to you is simply code your application first and then get your hands on a good profiler for your compiler / architecture and let it tell you where the bottlenecks are and concentrate on those areas.11/1/2007 7:39:33 PM |
aaronburro Sup, B 53068 Posts user info edit post |
really, if you are using a floating pt variable like that, I'd go w/ the fabs, myself, because the compiler will more than likely optimize that instruction beautifully, given the nature of how floating point values are stored.
as for memory overhead, I wouldn't worry about that as much unless memory is a super-tight concern. including a header-file would likely have little to no effect on performance, so use it, mang. 11/1/2007 8:02:40 PM |
synchrony7 All American 4462 Posts user info edit post |
Normally it is better to use functions that are parts of the standard C++ language than to try to roll your own.
These are functions that were put through committees, stood the test of time, and used millions of time. Odds are they are more error free and optimized than anything you will write. Odds are you aren't going to come up with a basic math function that is faster than the standard math functions.
^ Unless as the poster above points out that you know something very specific about your architecture that might allow you to optimize for your specific case in a way that the general case can't. 11/1/2007 8:06:56 PM |
philihp All American 8349 Posts user info edit post |
The most important reason to use x=fabs((float)var); is that it's short, and easiest to read, understand, and maintain. Chances are, SOMEONE (even yourself) is going to come upon this code in a year or two and wonder what the purpose of it was. 11/1/2007 8:55:32 PM |
Chop All American 6271 Posts user info edit post |
wow, way more response than i anticipated, thanks. i'm pretty sure fabs comes from math.h. the guy who is handling the hardware development and power supply code said to avoid using anything from any library functions, and avoid things like using the division operator (ie use x=theta * .01745 rather than x= theta * pi/180, use lookup tables for sin or cos functions, etc) 11/1/2007 9:34:54 PM |
Chance Suspended 4725 Posts user info edit post |
^^ You need to step into the world of micro controllers. In many cases where an RTOS is the norm, maintainable code takes not even a back seat, but gets a spot on the roof rack above.
Any idea how fast your micro will run? How much processing are you needing to do with each sample? Also, what controller is this that is being developed where some commercially available mcu can't do the same job? I mean, I can envision plenty of situations where a custom rolled one is needed/used, just surprised to see it pop up on tdubs radar.
JaegerNCSU, I've seen you post on and off over the years here, and I think I remember that you are a game developer. I was wondering, where did you get your knowledge about C, C++ and etc. Did you have a really really strong background, then just developed it on the job over time? The last time I saw anyone post in this section with command of a subject matter I thought was particularly impressive was when John Borwic (sp?) the NCSU perl guru answered a couple of perl questions and properly blew everyone's mind.
^ Umm, like most people have mentioned, if you have a good complier (and they have come a long ways) you'll have a hard time beating it in C alone. Dr. Dean told us when I was at NCSU, most stuff that was RT and cost sensitive (meaning least amount of memory and slowest clk) ended up being coded by hand in assembly to shrink it and make it run as fast as possible.
] 11/1/2007 9:50:27 PM |
Nitrocloud Arranging the blocks 3072 Posts user info edit post |
x &= 0x7FFFFFFF;
Assuming that this is a 4 byte floating variable. Consult your manuals, but the first bit in IEEE floating point numbers is your sign. This is a single operation for many microcontrollers.
[Edited on November 2, 2007 at 1:06 AM. Reason : detail] 11/2/2007 1:04:34 AM |
JaegerNCSU Veteran 245 Posts user info edit post |
^^ I started programming in C when I was 9, and read every book I could find about programming and computers at my local library. When I ran out of books there, I saved my lawn mowing money and had my mom drive me an hour away to the nearest town with a decent bookstore and bought new books. My senior year in high school I had an interpship / job with a certain Texas-based game developer and flew from NC to Dallas and back to work on the weekends. I got a CSC degree from NCSU, but that was a huge waste of time; just did it to say I had a degree. I own my own company now.
^ I gave him a fast (much faster than his branching, anyway) implementation just like that that assumes 32-bit IEEE floats. You can do similar tricks for negating the number or getting at the sign of the number.
To the OP, it sounds like you need a better understanding of your architecture and how your compiler produces code for your architecture before you're going to be able to write performance code for it. If your hardware guy says "don't use anything from the C or C++ standard libraries," you're going to be in for a rough time developing it because you're going to have to re-invent the wheel to get anywhere and if that's the case you should implement your standard library replacements in optimized assembler for your architecture with as many shortcuts as possible (since, afterall, you're in control of the hardware and know its exact performance specifications and how to sqeeze every bit of performance out of it). Also, you'll likely be dealing with lots of pointers in your code so you should investigate whether or not your compiler suppports the __restrict keyword or something similar to tell the compiler there is no pointer aliasing going on. One of the hardest things for the compiler to determine is which pointers alias which other pointers in a given scope, so telling it (rather promising to it as the compiler doesn't verify it) explicity allows it to do some optimizations and instruction rescheduling internally. 11/2/2007 2:03:59 AM |
Chop All American 6271 Posts user info edit post |
Quote : | "To the OP, it sounds like you need a better understanding of your architecture and how your compiler produces code for your architecture before you're going to be able to write performance code for it. If your hardware guy says "don't use anything from the C or C++ standard libraries," you're going to be in for a rough time developing it because you're going to have to re-invent the wheel" |
yeah, this pretty much sums it up. this is my first experience with programming microcontrollers and programming anything outside matlab since college. i'm not sure how i got put on this project, i'm friggin M.E. for crying out loud. let me turn some wrenches or something.11/2/2007 10:44:26 PM |
brokenbit Starting Lineup 82 Posts user info edit post |
there seems to be alot of people that know alot about the subject. just wondering, does you compiler have the capibility to handle inline assembly. thats the route i would take. 99 times out of 100 you can get huge efficiency increase there.
if you want help with how to do that consult Mr Dana Lasher, he is the asm prof at state. he is a cook, but a wiz and will be able to show you the best wat to optimize the code.
here is his page address http://www.csc.ncsu.edu/directories/faculty_info.php?id=142 11/3/2007 4:51:33 AM |
philihp All American 8349 Posts user info edit post |
Quote : | "x &= 0x7FFFFFFF; " |
like many programming problems, i was thinking about this one in the shower and figured you could just mask it too gg11/4/2007 2:53:56 PM |
Chop All American 6271 Posts user info edit post |
couple of things:
1. I decided to go with the fabs method until i'm sure i have the algorithm logic correct. I'm surprised no one called me out on this, apparently fabs returns a double, fabsf returns a float not a big deal, just an annoyance.
2. is it faster to use array variables or pointers? (please say pointers, as i spent some time coding a lookup table structure class using pointers) if i understand it correctly, pointers point directly to the memory address so it should be faster, right?
3. i'm also getting a type conversion from float to double on a function return, not sure why. any thoughts? Hopefully this isn't too vague, it looks something like this (Note - arg4 is a calculated asin number stored in a lookup table, i'm thinking this might have something to do with it):
float functionName (float arg1, float arg2, float arg3, float arg4) { if ( someCondition(arg1,arg2) = true ) { return( doSomeStuff(arg3,arg4) ); else { return(0); } }
the compiler gives a warning on both return lines that about loss of data due to conversion from float to double. i'm not sure why there's a conversion.11/10/2007 11:39:34 PM |
JaegerNCSU Veteran 245 Posts user info edit post |
Quote : | "2. is it faster to use array variables or pointers? (please say pointers, as i spent some time coding a lookup table structure class using pointers) if i understand it correctly, pointers point directly to the memory address so it should be faster, right?" |
It all depends on the situation and architecture and since you didn't specify the specific circumstances I'm going to assume you're simply talking about indexing. In terms of simple indexing, pointers and arrays are roughly the same speed. In C and C++, an array is simply a pointer to the first element and indexing into an array boils down to simple pointer arithmetic. It's a bit different beyond simple indexing and depends on exactly what's going on.
Quote : | "3. i'm also getting a type conversion from float to double on a function return, not sure why. any thoughts? Hopefully this isn't too vague, it looks something like this (Note - arg4 is a calculated asin number stored in a lookup table, i'm thinking this might have something to do with it):
float functionName (float arg1, float arg2, float arg3, float arg4) { if ( someCondition(arg1,arg2) = true ) { return( doSomeStuff(arg3,arg4) ); else { return(0); } }
the compiler gives a warning on both return lines that about loss of data due to conversion from float to double. i'm not sure why there's a conversion." |
You mean from double to float, which would lose data. The return 0 is simple if you follow my advice from my first post:
Quote : | "You should also help the compiler out by using 0.0f if you want a float." |
When you simply put 0 the compiler will interpret that as a double when doing floating point stuff. Change it to return 0.0f and the problem on that line will go away. For the problem on the other line, you didn't show the declaration of doSomeStuff(), but I'm betting it returns a double and not a float. You'll need to change it to work with floats and not doubles. Or you could cast it to get rid of the warning like this: return static_cast<float>(doSomeStuff(arg3, arg4)) but you should know that doing that only gets rid of the warning and doesn't fix the actual loss of data condition. Note that I'm assuming that the error is with the actual return value here because you only said that it gives the error on the return line and not specifically which part of the line was giving the error.
You're also using the assignment operator in your someCondition() conditional rather than an equality test, and you don't need to test for true in that way; a simple if( someCondition() ) will suffice.
Since you're dealing with floating point numbers everywhere, I thought I'd mention that you shouldn't be simply testing for equality with == ... you should be using an epsilon test. Consult google for how and why.11/11/2007 1:11:12 AM |
Chop All American 6271 Posts user info edit post |
yeah, i meant its converting from double to float, i'm not sure where the double is coming from. its only a warning and doesn't prevent the code from compiling, i'd just rather avoid the the double calculations if possible. i missed the 0.0f thing in your first post, that will probably fix most of it.
yeah, the pointer/array thing is simply indexing.
the code i put up here is just something i slapped together from memory, i thought the doSomeStuff() function returned a float, but maybe not. i'll check it out. i'll check out the ellipse thing too. i'm going to guess it has something to do with wrap around or whatever its called?
btw i'm using MS Visual Studio C something-or-another
[Edited on November 11, 2007 at 4:21 PM. Reason : .] 11/11/2007 4:21:01 PM |
Wolfmarsh What? 5975 Posts user info edit post |
In case you didnt know, JaegerNCSU is the shizzle. 11/11/2007 7:23:15 PM |
BigMan157 no u 103354 Posts user info edit post |
i miss microcontroller programming 11/11/2007 8:40:49 PM |
Chop All American 6271 Posts user info edit post |
is there an easy way to determine the maximum of list of short int values without using math.h? i was looking through the help, and came across a max function, but i didn't understand the example they used. if i remermber correctly it was something like:
MAX dc @MAX(2, 5, 3);
result: MAX=5
what does the dc thing do? i tried doing something like x=@MAX(exp1, exp2, exp3); but the compiler says max is an undeclared function.
this is with Metrowerks CodeWarrior IDE, if it matters.12/14/2007 6:59:21 PM |
bous All American 11215 Posts user info edit post |
Quote : | "like many programming problems, i was thinking about this one in the shower and figured you could just mask it too gg" |
uhhhh you think about programming in the shower?12/14/2007 10:23:26 PM |
BigMan157 no u 103354 Posts user info edit post |
count sort or quick sort? 12/14/2007 11:28:47 PM |
scud All American 10804 Posts user info edit post |
depends on the application - probably mergesort or heapsort 12/14/2007 11:34:37 PM |
skokiaan All American 26447 Posts user info edit post |
Maybe I don't understand what he is doing, but, if he's just trying to get the max of a random list of numbers, just search the list linearly. That's faster than any of those sorts. 12/15/2007 12:58:18 AM |
philihp All American 8349 Posts user info edit post |
is the length of the list always the same? 12/15/2007 2:12:18 AM |
Chop All American 6271 Posts user info edit post |
Quote : | "is the length of the list always the same?" |
yes, it is 5 different calculated values, and i simply need to find the largest of these values.
Quote : | "probably mergesort or heapsort" |
how does this work? i'm still learning all this as i go. i supposed google knows the answer if i'm really interested. . .12/15/2007 10:28:12 AM |
dakota_man All American 26584 Posts user info edit post |
Carmack's magic inverse square root function:
http://www.codemaestro.com/reviews/9 12/15/2007 1:55:20 PM |
JaegerNCSU Veteran 245 Posts user info edit post |
^ fwiw, Carmack did not write that code.
and ^^ if you only ever have 5 values, just compute the max value yourself in a loop; no need to sort 5 values.
[Edited on December 15, 2007 at 6:21 PM. Reason : .] 12/15/2007 6:19:33 PM |
dakota_man All American 26584 Posts user info edit post |
Yeah, I googled that hex number and from what I could find nobody knows who wrote it. 12/16/2007 12:45:53 PM |