Author | Message | Time |
---|---|---|
Gnathonic | I'm using Microsoft VC++ 6.0, and I currently have about 6 hours experiance with C++ total so my code needs a bit of help, but what I have works it just isn't very fast. How would one optimize this code for speed, and reduced arrayiable size, and whatever else can be helped? [code] #include "filter.h" Pixel32 Frame[2][1600][1200]; [/code]This is the current and past frame storage array. [code] int TFrame[2][1600][1200][3]; [/code]This is a temp array, used so that seperation of colors is done only once. [code] int runProc(const FilterActivation *fa, const FilterFunctions *ff); int tutorialRunProc(const FilterActivation *fa, const FilterFunctions *ff) { PixDim w, h; [/code]counter array: w for frame width, h for frame hight. [code] Pixel32 *src, *dst; [/code] I don't fully understand this one but the *src provides the source frame pixel by pixel, and the *dst provides a way to output the frame, pixel by pixel. [code] LONGLONG DifAA, DifAB, DifBA; [/code]field combination diference colection arrays. [code] int i; [/code]a counter array. [code] DifAA = 0; DifAB = 0; DifBA = 0; [/code]resets arrays value to 0. I think? [code] src = (Pixel32 *)fa->src.data; [/code]points the src array to the pixels in the source frame [code] h = fa->src.h; [/code]sets counter array to the frame height [code] do { w = fa->src.w; [/code]sets counter array to the frame width [code] do { Frame[0][w][h] = *src++; [/code]stores frame for easy referance, and to referance back to. [code] TFrame[0][w][h][0] = (Frame[0][w][h] & 0xFF0000) / 0x010000; TFrame[0][w][h][1] = (Frame[0][w][h] & 0x00FF00) / 0x000100; TFrame[0][w][h][2] = (Frame[0][w][h] & 0x0000FF); [/code]seperates the color into its components (Red, Green, Blue) and reduces value of red, and green so that calculations are more accurate and not weighted to some color. [code] } while(--w); src = (Pixel32 *)((char *)src + fa->src.modulo); [/code]moves the src array to the next row in the frame. I think? [code] } while(--h); dst = (Pixel32 *)fa->dst.data; [/code]set the dst array to output the processed frame, pixel by pixel. [code] h = fa->src.h; [/code]sets counter array [code] do { w = fa->src.w; [/code]sets counter array [code] do { for(i=0; i<3; i++) { DifAA += abs(TFrame[0][w][h][i] - TFrame[0][w][h+1][i]); DifAB += abs(TFrame[0][w][h][i] - TFrame[1][w][h+1][i]); DifBA += abs(TFrame[1][w][h][i] - TFrame[0][w][h+1][i]); [/code]compairs the fields from each frame against each other to find the one with the least difference In order: current frame against its own fields. bottom field from the current frame and the top field from the past frame. top field from the current frame and the bottom field from the past frame. The "for" statement and counter rotate through the RGB colors that were seperated earlier in the code. [code] } } while(--w); --h; } while(--h); [/code]from here to [code] if((DifAA<=DifAB) && (DifAA<=DifBA)) { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[0][w][h]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } else if((DifAB<DifAA) && (DifAB<DifBA)) { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[0][w][h]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); w = fa->src.w; --h; do { *dst++ = Frame[1][w][h]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } else { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[1][w][h]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); w = fa->src.w; --h; do { *dst++ = Frame[0][w][h]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } [/code]here is the code for outputing the field combination that can best reduce interlacing artifacts (according to the calcuations used prior). [code] h = fa->src.h; do { w = fa->src.w; do { Frame[1][w][h] = Frame[0][w][h]; for(i=0; i<3; i++) { TFrame[1][w][h][i] = TFrame[0][w][h][i]; } } while(--w); } while(--h); [/code] this whole thing moves the values from our current frame to our past frame section of the array. [code] return 0; } [/code] | February 28, 2005, 9:16 PM |
EpicOfTimeWasted | First and foremost I'd edit your post and put [ code ] [ /code ] tags around the code in your post, so it's more readable. | February 28, 2005, 9:35 PM |
Gnathonic | Sorry about that. I can see what you mean. Is this better? *edits first post.* Oh, one request if you post any optimizations could you explain it, I mean at least the code so that when I write more code I can include that kind of optimizations in it? | February 28, 2005, 10:47 PM |
Arta | You are far better off letting the compiler optimise your code. I don't know where the settings are in VC++ 6, but you can tell the compiler to optimise your code for speed or size, as well as change various other settings. The first thing I would suggest is changing to a release build form a debug build, if you haven't already. PS: Are those Frame/TFrame arrays always that size? Could they be allocated using new/malloc to reduce your memory consumption? | March 1, 2005, 2:57 AM |
Kp | IIRC, VC++ 6 "Standard" edition cannot optimize. Given that he's relatively new to C++, I doubt he's bought a higher version than that. If so, the options are either to get a higher grade VC++ or switch to MinGW (warning: MinGW is command-line driven, not for newbies or WIMP addicts). | March 1, 2005, 5:25 AM |
po0f | An int array of 2x1600x1200x3? IIRC ints are 4 bytes; 4*2*1600*1200*3 = 46080000 bytes / 1024 = 45000MB!! That might be your speed issue right there. | March 1, 2005, 7:12 AM |
Adron | 45 MB, not GB, but yes, it's not going to be lightning fast whatever he does. Looking at your code, do you want your output to be an array of integers, not an array of RGB values? That intermediate integer array is going to slow down the code by a huge amount because of memory access latency. It may be very much faster to just do the splitting for each pixel, as you will save on memory accesses and the CPU speed typically is many times higher than the memory speed. Same goes for if you don't *have* to divide each pixel into 3 4-byte values, the less memory you use, the faster it will be. | March 1, 2005, 10:07 AM |
Gnathonic | [quote author=Arta[vL] link=topic=10760.msg102036#msg102036 date=1109645843] You are far better off letting the compiler optimise your code. I don't know where the settings are in VC++ 6, but you can tell the compiler to optimise your code for speed or size, as well as change various other settings. The first thing I would suggest is changing to a release build form a debug build, if you haven't already.[/quote] I did set the compiler to optimize the code for speed, but it did very little. I also set it to the release build setting, and that didn't impove the speed, at least not to a noticeable extent. It did reduce the program size from 224K to 20K. [quote author=Arta[vL] link=topic=10760.msg102036#msg102036 date=1109645843] PS: Are those Frame/TFrame arrays always that size? Could they be allocated using new/malloc to reduce your memory consumption? [/quote] Yes I didn't know how to resize them, like I said I'm very new at this language. How does one use the new/malloc comands? [quote author=Kp link=topic=10760.msg102055#msg102055 date=1109654730] IIRC, VC++ 6 "Standard" edition cannot optimize. Given that he's relatively new to C++, I doubt he's bought a higher version than that. If so, the options are either to get a higher grade VC++ or switch to MinGW (warning: MinGW is command-line driven, not for newbies or WIMP addicts). [/quote] I'm using the Enterprize edition. It's inbetween the standard and pro editions of the program. [quote author=Adron link=topic=10760.msg102067#msg102067 date=1109671640] Looking at your code, do you want your output to be an array of integers, not an array of RGB values? That intermediate integer array is going to slow down the code by a huge amount because of memory access latency. It may be very much faster to just do the splitting for each pixel, as you will save on memory accesses and the CPU speed typically is many times higher than the memory speed. Same goes for if you don't *have* to divide each pixel into 3 4-byte values, the less memory you use, the faster it will be. [/quote] I just want something that is fast I don't really care what arrays it uses just as long as it works, fast. When I was making this program the guide I was using said it was a good idea to minimize the division used, so I made the temp array so that would only be done once, but I will try that when I get back to my PC, it makes sense to me that that might work. Thanks for you help thus far. In the mean time is there a way to optimize the code in the difference calc loop as it was segested, so that it runs faster? EX. [code] h = fa->src.h; do { w = fa->src.w; do { DifAA += abs((Frame[0][w][h] & 0xFF0000) - (Frame[0][w][h+1] & 0xFF0000)) / 0x010000 + abs((Frame[0][w][h] & 0x00FF00) - (Frame[0][w][h+1] & 0x00FF00)) / 0x000100 + abs((Frame[0][w][h] & 0x0000FF) - (Frame[0][w][h+1] & 0x0000FF)); DifAB += abs((Frame[0][w][h] & 0xFF0000) - (Frame[1][w][h+1] & 0xFF0000)) / 0x010000 + abs((Frame[0][w][h] & 0x00FF00) - (Frame[1][w][h+1] & 0x00FF00)) / 0x000100 + abs((Frame[0][w][h] & 0x0000FF) - (Frame[1][w][h+1] & 0x0000FF)); DifBA += abs((Frame[1][w][h] & 0xFF0000) - (Frame[0][w][h+1] & 0xFF0000)) / 0x010000 + abs((Frame[1][w][h] & 0x00FF00) - (Frame[0][w][h+1] & 0x00FF00)) / 0x000100 + abs((Frame[1][w][h] & 0x0000FF) - (Frame[0][w][h+1] & 0x0000FF)); } while(--w); } while(--h); [/code] | March 1, 2005, 4:41 PM |
Kp | Don't know if your compiler is smart enough to be optimizing that, but yes, I can see a few speedups to the supplied loop. Replace the statements of the inner do { ... } as follows: [code]int x = Frame[0][w][h], y = Frame[0][w][h+1]; /* Now refer to x where you would've used Frame[0][w][h], etc. This hints to the compiler that it's OK to cache these in registers. You can reassign x and y after your modifications to DifAA are done. Do the same caching for the other equations. * Also, use >> 16 instead of / 0x10000, and >>8 instead of /0x100. The compiler ought to be doing that for you, but no guarantees without looking at the object code. */[/code] | March 1, 2005, 10:25 PM |
Gnathonic | I did all the the optimizations, except the last, and the new/malloc which I plan to add soon (15 - 20 minutes from now?), and the program doubled it's speed *yea!*... But sadly when I looked up the new/malloc commands I became extremely confused, and trying to read about it here didn't help much. Could one of you just give me that code. I think I might be able to get it when I have an example I'm familar with, but then maybe not in which case I'm going to have to deal with a headache while I try to get what they are trying to teach me at those other places. array name: Frame Things with desired array demensions: fa->src.h fa->src.w | March 2, 2005, 5:34 AM |
Kp | [code]int *i = (int*)malloc(sizeof(int) * number_of_ints_needed); if (!i) die ("Out of memory"); /* You now have an array of integers. */[/code] Alternately, [code]int *i = new int[number_of_ints_needed]; /* If out of memory, new already crashed your program with an exception */[/code] | March 3, 2005, 2:20 AM |
Mephisto | Unless of course you properly handle the allocation exception which is always good to do. [code] try { int *i = new int[number_of_ints_needed]; } catch(bad_alloc &exception) { printf("Exception occured when calling operator new: %s", exception.what()); }[/code] | March 3, 2005, 3:29 AM |
Gnathonic | [quote author=Kp link=topic=10760.msg102255#msg102255 date=1109816455] [code]int *i = (int*)malloc(sizeof(int) * number_of_ints_needed); if (!i) die ("Out of memory"); /* You now have an array of integers. */[/code] Alternately, [code]int *i = new int[number_of_ints_needed]; /* If out of memory, new already crashed your program with an exception */[/code] [/quote] I'm looking at this and getting progressively more confused. Although new seams to make more sence than the malloc one. I still can't tell what goes where!!! When I learned C++ I learned it from looking at some source code and a small, may I enphasize that again, small guide, because of this seeing the above provided code doesn't give me a single clue as to what to do. Would any one who understands that code, and the function of these arrays/calls/whatever: Frame fa->src.h fa->src.w Pixel32 tell me where they would go? | March 3, 2005, 8:10 AM |
Kp | [quote author=SoR-Mephisto link=topic=10760.msg102272#msg102272 date=1109820542]Unless of course you properly handle the allocation exception which is always good to do.[code] try { int *i = new int[number_of_ints_needed]; } catch(bad_alloc &exception) { printf("Exception occured when calling operator new: %s", exception.what()); }[/code][/quote] I suppose, although exception handling is generally so slow that I just turn off exception support entirely and use the variant that returns NULL instead of throwing a bad_alloc exception. Which, btw, you forgot to mention is in namespace std. ;) Unless he puts in a [u]using std::bad_alloc;[/u], your code won't work due to bad_alloc being unrecognized in the primary namespace. Gnathonic: although you're considerably better spoken than most newbies we get here, the forum has a long tradition against just giving code because invariably it ends up causing more questions than it answered. From what you've kept reiterating, it seems to me that the number of ints needed would be the product of fa->src.{h,w}, no? Frame would be of type Pixel32 and would store the returned results of new. | March 3, 2005, 3:02 PM |
Gnathonic | O.K. for the sake of working within you peoples "tradition" (yes I had noticed a lack of code responses), which just so happens to work against the way I learned VB, and C++ thus far, but here goes... Is the first int the int command? array name? (doubt this one) or int array type? I don't even have a guess what this is *i the new statement seams simple enough Is this second int... just see the first list. The last one makes sence. Like I said that whole thing was making me confused. | March 3, 2005, 4:27 PM |
Arta | 'int' is the data type (integer). The * before the identifier (i) indicates that you are creating a pointer to an int, rather than the int itself. 'new' is an operator which allocates memory - in simpler terms, it creates new variables. The second 'int' tells 'new' that you wish to allocate space for an integer variable. The square brackets denote the number of ints you wish to allocate. This may seem confusing, but arrays and pointers are basically interchangeable in C/C++. An array is simply a pointer to the first item in the array, and square brackets (more formally, the subscript operator) can be used with array and pointer types. So, all together, the line: [code] int *i = new int[number_of_ints_needed]; [/code] Means: Create an identifier, i, which is a pointer to an integer. Allocate enough memory to store number_of_ints_needed integers and place the starting address for that block of memory in the pointer variable i. | March 3, 2005, 4:55 PM |
Myndfyr | [quote author=Arta[vL] link=topic=10760.msg102325#msg102325 date=1109868949] This may seem confusing, but arrays and pointers are basically interchangeable in C/C++. An array is simply a pointer to the first item in the array, and square brackets (more formally, the subscript operator) can be used with array and pointer types. [/quote] To explain why this is: Let's say you declare an array of ints, 5 items long. You could do either one of these statements: [code] int i[5] = new int[5]; // or int *i = new int[5]; [/code] When you declare this array -- either way you do it -- you're telling the compiler to set aside some memory for your use. So really, you're getting some memory. Each "slot" in memory has a specific address. The type int on 32-bit computers takes up 32 bits, or 4 bytes. Arrays are stored contiguously -- which means that all of the items are right next to each other. So, let's say that you get the address: 0x10048540 as the value of "i". That is the address of the first item in your array. How do you get at the second one? Well, if you know that the first one takes up four bytes of space, and that the items in the array all line up right next to each other -- just add four to the original address! 0x10048544! How does this apply? As Arta said, pointers and arrays are generally interchangeable. When you declare memory plainly using malloc(), these statements can still be equivalent: [code] int *i = new int[5]; // this is the second one from above) int *i = malloc(5 * sizeof(int)); [/code] Note the sizeof operator, which determines the amount of memory a specific type takes up. malloc() is used primarily in C, where the new operator is not available. Generally, C++ users use new because it's more clear. All told, these loops mean pretty much the same thing: [code] // loop A int *i = new int[5]; for (int c = 0; c < 5; c++) { *(i + c * sizeof(int)) = c; cout << "i[" << c << "] = " << *(i + c * sizeof(int)) << std::endl; } // loop B int i[5] = new int[5]; for (int c = 0; c < 5; c++) { i[c] = c; cout << "i[" << c << "] = " << i[c] << std::endl; } // loop C int *i = new int[5]; for (int c = 0; c < 5; c++) // watch this loop, it is the coolest. { *i = c; // dereference i, assign the c to the value pointed at cout << "i[" << c << "] = " << *i++ << std::endl; // after getting the value pointed to, increment the pointer } [/code] The first one is tough to grasp, but think about how it runs and how it applies to oddly-sized values such as structures and classes. Note that the expression inside the parenthesis: i + c * sizeof(int) is the pointer that's being dereferenced. Let's say i contains that value I gave you before, 0x10048540. Run it through: [code]int *i = new int[5];[/code] i = 0x10048540 [code] for (int c = 0; c < 5; c++) { *(i + c * sizeof(int)) = c; cout << "i[" << c << "] = " << *(i + c * sizeof(int)) << std::endl; } [/code] Iteration 1: c = 0. (i + c * 4) = 0x10048540. *(0x10048540) = 0, which is the value of c. Iteration 2: c = 1. (i + c * 4) = 0x10048544. *(0x10048544) = 1, which is the value of c. Iteration 3: c = 2. (i + c * 4) = 0x10048548. *(0x10048548) = 2, which is the value of c. Iteration 4: c = 3. (i + c * 4) = 0x1004854c. *(0x1004854c) = 3, which is the value of c. Iteration 5: c = 4. (i + c * 4) = 0x10048550. *(0x10048550) = 4, which is the value of c. Loop B is pretty obvious -- but wait. What about loop C? Loop C changes the value of the pointer variable, which is fine if you're working with a local variable and you have a copy of the original pointer available. If you overwrite the only copy of the pointer, though, how do you know where your array began? Let's look at this code closely: [code] // the loop body. *i = c; // dereference i, assign the c to the value pointed at cout << "i[" << c << "] = " << *i++ << std::endl; // after getting the value pointed to, increment the pointer [/code] The first time the loop runs, c will be 0, so we don't need to change where we're pointing to. So, *i = c means, store the value of c in the location in memory where i points. i points at 0x10048540, and 0 is being stored there. The second line is an expression that prints to the console. It works just like all the others, with this exception: [code]*i++[/code] This code says, "Get the value that i is pointing to, and then increment i by the size of its type." The C++ compiler is smart enough to remember what kind of variable i is -- remember, it's a pointer to an integer. An integer is 4 bytes large. When we say to increment a pointer, we want it to point to the next location in memory in which an integer is held, so the compiler does it automatically for us. Iteration 1: i = 0x10048540. Iteration 2: i = 0x10048544. Iteration 3: i = 0x10048548. Etcetera. Hope this wasn't too much for you at once! | March 4, 2005, 12:43 AM |
Kp | [quote author=MyndFyre link=topic=10760.msg102375#msg102375 date=1109897022] To explain why this is: Let's say you declare an array of ints, 5 items long. You could do either one of these statements: [code] int i[5] = new int[5]; // or int *i = new int[5]; [/code][/quote] Actually, no, you can't. :) Observe:[code]/tmp> cat tst.cc int* foo() { int i[5] = new int[5]; return i; } /tmp> g++ -c tst.cc g++ -c tst.cc tst.cc: In function `int* foo()': tst.cc:2: error: invalid initializer [/code]Short explanation is that [u]int i[5] = new int[5];[/u] is nonsense and prohibited. Also, a couple of other notes: [quote author=MyndFyre link=topic=10760.msg102375#msg102375 date=1109897022] As Arta said, pointers and arrays are generally interchangeable. When you declare memory plainly using malloc(), these statements can still be equivalent: [code] int *i = new int[5]; // this is the second one from above) int *i = malloc(5 * sizeof(int)); [/code] Note the sizeof operator, which determines the amount of memory a specific type takes up. malloc() is used primarily in C, where the new operator is not available. Generally, C++ users use new because it's more clear.[/quote] malloc returns a void*, which can be implicitly cast to int* in C, but not in C++. So, those statements are not equivalent since the second one won't compile without a cast. Also, operator new implicitly calls an appropriate constructor, whereas malloc does not. Thus, it's extremely ill-advised (though quite legal) to use malloc to allocate a non-POD type. Come to think of it, that kind of wizardry is required if you want to allocate an array and use a non-default constructor. [quote author=MyndFyre link=topic=10760.msg102375#msg102375 date=1109897022]All told, these loops mean pretty much the same thing: [code] // loop A int *i = new int[5]; for (int c = 0; c < 5; c++) { *(i + c * sizeof(int)) = c; cout << "i[" << c << "] = " << *(i + c * sizeof(int)) << std::endl; } // loop B int i[5] = new int[5]; for (int c = 0; c < 5; c++) { i[c] = c; cout << "i[" << c << "] = " << i[c] << std::endl; } // loop C int *i = new int[5]; for (int c = 0; c < 5; c++) // watch this loop, it is the coolest. { *i = c; // dereference i, assign the c to the value pointed at cout << "i[" << c << "] = " << *i++ << std::endl; // after getting the value pointed to, increment the pointer } [/code][/quote]Actually, only loop C will even work correctly. :) Loop A falls prey to the very thing you're trying to show him: implicit pointer arithmetic. 'i' is of type 'int', so the compiler is automatically multiplying c by sizeof(int) (more correctly, by sizeof(*i), which happens to be sizeof(int)), so doing it explicitly means you multiply by 16 instead of 4. Loop B won't compile due to the aforementioned illegality of assigning a new int[5] to an int[5]. | March 4, 2005, 2:12 AM |
Myndfyr | Appreciate the corrections Kp <3 I thought I might be thinking in C. | March 4, 2005, 9:27 AM |
Gnathonic | After much tinkering, I finally got it. I didn't quite realize what one part of my problem was, but as for the other part, Thanks Arta. Although it took me awhile to get what you were talking about with the "i" thing, I hadn't heard anyone call vars / pointers an "identifier" before so I thought you were talking about something else. After that I got confused wondering how I would call upon an unlabeled array. So I went back to your code and just kind of stared at it trying to find any way to call the array. Then it hit me. "i" = "identifier", "identifier" = array name, this experiance = epiphany. Afterwords I kind of smacked my self up side the head while saying duh to myself. Of well, thanks anyways for your posts MyndFyre and Kp. They were both informative and humorous. Here's my code as it stands. If you can think of anything to speed it up it would be helpful, cause all the things I knew of I already added. [code] #include "filter.h" int runProc(const FilterActivation *fa, const FilterFunctions *ff); int RunProc(const FilterActivation *fa, const FilterFunctions *ff) { PixDim w, h; Pixel32 *src, *dst; LONG DifAA, DifAB, DifBA; static Pixel32 *Frame = new Pixel32[2*fa->src.h*fa->src.w]; DifAA = 0; DifAB = 0; DifBA = 0; src = (Pixel32 *)fa->src.data; h = fa->src.h; do { w = fa->src.w; do { Frame[w+h*(fa->src.w)+fa->src.h*fa->src.w] = Frame[w+h*fa->src.w]; Frame[w+h*fa->src.w] = *src++; } while(--w); src = (Pixel32 *)((char *)src + fa->src.modulo); } while(--h); dst = (Pixel32 *)fa->dst.data; h = fa->src.h; do { w = fa->src.w; do { DifAA += (abs(((Frame[w+h*fa->src.w] & 0xFF0000)) - (Frame[w+h*fa->src.w+fa->src.w] & 0xFF0000)) >>16)+ (abs(((Frame[w+h*fa->src.w] & 0x00FF00)) - (Frame[w+h*fa->src.w+fa->src.w] & 0x00FF00)) >>8)+ abs(((Frame[w+h*fa->src.w] & 0x0000FF)) - (Frame[w+h*fa->src.w+fa->src.w] & 0x0000FF)); DifAB += (abs(((Frame[w+h*fa->src.w] & 0xFF0000)) - (Frame[w+h*fa->src.w+fa->src.h*fa->src.w+1] & 0xFF0000)) >>16) + (abs(((Frame[w+h*fa->src.w] & 0x00FF00)) - (Frame[w+h*fa->src.w+fa->src.h*fa->src.w+1] & 0x00FF00)) >>8) + abs(((Frame[w+h*fa->src.w] & 0x0000FF)) - (Frame[w+h*fa->src.w+fa->src.h*fa->src.w+1] & 0x0000FF)); DifBA += (abs(((Frame[w+h*fa->src.w+fa->src.h*fa->src.w] & 0xFF0000)) - (Frame[w+h*fa->src.w+fa->src.w] & 0xFF0000)) >>16)+ (abs(((Frame[w+h*fa->src.w+fa->src.h*fa->src.w] & 0x00FF00)) - (Frame[w+h*fa->src.w+fa->src.w] & 0x00FF00)) >>8) + abs(((Frame[w+h*fa->src.w+fa->src.h*fa->src.w] & 0x0000FF)) - (Frame[w+h*fa->src.w+fa->src.w] & 0x0000FF)); } while(--w); --h; } while(--h); if((DifAA<=DifAB) && (DifAA<=DifBA)) { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[w+h*fa->src.w]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } else if((DifAB<DifAA) && (DifAB<DifBA)) { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[w+h*fa->src.w]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); w = fa->src.w; --h; do { *dst++ = Frame[w+h*fa->src.w+fa->src.h*fa->src.w]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } else { h = fa->src.h; do { w = fa->src.w; do { *dst++ = Frame[w+h*fa->src.w+fa->src.h*fa->src.w]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); w = fa->src.w; --h; do { *dst++ = Frame[w+h*fa->src.w]; } while(--w); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); } return 0; } [/code] | March 4, 2005, 10:31 AM |
Kp | Myndfyre: :) [quote author=Gnathonic link=topic=10760.msg102417#msg102417 date=1109932302]Although it took me awhile to get what you were talking about with the "i" thing, I hadn't heard anyone call vars / pointers an "identifier" before so I thought you were talking about something else.[/quote]Well, strictly speaking an identifier is more general than a variable. Consider the following:[code]void foo() { printf ("Foo!\n"); }[/code]foo is an identifier for the function defined, although foo is not a variable. All pointers are variables (even when they're constant), but not all variables are pointers. :) [quote author=Gnathonic link=topic=10760.msg102417#msg102417 date=1109932302]"i" = "identifier", "identifier" = array name[/quote]Just so you're clear on this point, "i" was an arbitrarily chosen name, and probably picked more out of convention than because he intended to talk about identifiers. Historically, C people use i, j, k, l, etc. in order as loop control or otherwise short-lived simple purpose variables. Of course, if your variable serves some purpose worth giving it another name (for example, your code uses 'w' as a copy of the width), that's quite ok too. Your prototype is unnecessary, for two reasons. First, you miscapitalized the name in the prototype. In C, names are case sensitive, so prototyping runProc tells the compiler nothing about RunProc. Second, you immediately thereafter define the function, and all modern compilers that I know of will use a definition as an implicit prototype if one has not been provided. You declare Frame as a static Pixel32 pointer, but then initialize it with values that are retrieved from the function invocation. That's dangerous, since if you call RunProc again with a larger set of parameters, Frame will not be reallocated to the new size. If you can stand the performance hit of the memory allocations, I'd recommend making Frame a non-static variable. If you do, don't forget to free it at the end. I note that you're still not using my suggestion about caching inside the loops, and it's dependent on your compiler and optimization level whether the compiler will be bright enough to strength reduce your loops for you. Aside from that and a few cases where you're doing a*b+c*b, which could be rewritten as (a+c)*b to reduce number of operations, the only other change I would suggest is positioning on the opening brace and doing an =% to fix your formatting. | March 4, 2005, 4:06 PM |
Adron | [quote author=Kp link=topic=10760.msg102439#msg102439 date=1109952379] All pointers are variables (even when they're constant), but not all variables are pointers. :) [/quote] *(char*)0x401000 = 0; int i = 0; 1[(char*)&i] = 'a'; (char*)&i and 0x401000 aren't variables though? Pointers can also just be constant or non-constant expressions. | March 4, 2005, 5:46 PM |
Kp | [quote author=Adron link=topic=10760.msg102456#msg102456 date=1109958402][quote author=Kp link=topic=10760.msg102439#msg102439 date=1109952379]All pointers are variables (even when they're constant), but not all variables are pointers. :)[/quote]*(char*)0x401000 = 0; int i = 0; 1[(char*)&i] = 'a'; (char*)&i and 0x401000 aren't variables though? Pointers can also just be constant or non-constant expressions.[/quote] Bleh, don't confuse him with complex constructs. He wasn't even tracking our memory allocation code without deep explanation. | March 4, 2005, 7:24 PM |
Adron | [quote author=Kp link=topic=10760.msg102464#msg102464 date=1109964259] [quote author=Adron link=topic=10760.msg102456#msg102456 date=1109958402][quote author=Kp link=topic=10760.msg102439#msg102439 date=1109952379]All pointers are variables (even when they're constant), but not all variables are pointers. :)[/quote]*(char*)0x401000 = 0; int i = 0; 1[(char*)&i] = 'a'; (char*)&i and 0x401000 aren't variables though? Pointers can also just be constant or non-constant expressions.[/quote] Bleh, don't confuse him with complex constructs. He wasn't even tracking our memory allocation code without deep explanation. [/quote] Yes, yes, just don't teach him broad generic statements such as "all pointers are variables" when there are actually pointers that aren't :P To him: Having an expression that is a pointer isn't that uncommon actually, my examples are just weird because I wanted to make them without declaring a lot of variables, structures, etc. | March 5, 2005, 4:40 AM |
Mephisto | [quote author=Kp link=topic=10760.msg102439#msg102439 date=1109952379] Well, strictly speaking an identifier is more general than a variable. Consider the following:[code]void foo() { printf ("Foo!\n"); }[/code]foo is an identifier for the function defined, although foo is not a variable. All pointers are variables (even when they're constant), but not all variables are pointers. :)[/quote] Isn't foo actually a variable being a pointer to the function? I'm under the impression that all function names are actually pointers, and from your example a pointer is a variable (in most cases). | March 5, 2005, 6:25 AM |
Gnathonic | (uh conversation and lots of er whatever...) I'll start from my last post. Everything that I used in my code came from this example code in a small tutorial on the VDub filter system: [code] #include "filter.h" int runProc(const FilterActivation *fa, const FilterFunctions *ff); int RunProc(const FilterActivation *fa, const FilterFunctions *ff) { PixDim w, h; Pixel32 *src, *dst; src = (Pixel32 *)fa->src.data; dst = (Pixel32 *)fa->dst.data; h = fa->src.h; do { w = fa->src.w; do { Pixel32 old_pixel, new_pixel; old_pixel = *src++; new_pixel = (old_pixel & 0xFF0000) + ((old_pixel & 0x00FEFE)>>1) + 0x008000; *dst++ = new_pixel; } while(--w); src = (Pixel32 *)((char *)src + fa->src.modulo); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); return 0; } [/code]I simply thought the code had to be there, thanks for offering that bit of information, like everything else I will take that into note and take advantage of it later. As far as the static declaration that won't be a problem. Everytime the resolution (or anything for that matter) is changed, VDub will unload and reload all the filters , and video resoltion can not change in mid-film so that's not a problem either, but thanks anyways, and sorry for not having explaned the VDub filter system in the slightest. Since I'm at it, the program has other code, but it's just VDub stuff, if you want I can post it but you probably won't find anything interesting in it. This code gets compiled as an dll, if that helps with anything. I tried using your caching code stuff but found myself unable. Is there anything more then what you posted that you think I should know in order to be able to use it. Or this might work instead of explaning several functions to the point where any fool can grasp it just give me some exaple code that covers the following: caching a var to whatever you would call them (can you teach me the terminalogy here?), and then caching a different var to the same what ever you would call them (I need to learn the terms I feel dumb every time I say something like that.). Ok, the math simplafication thing doesn't go over too well on a sleep deprived brain, that's something I should have cought, thanks. When it comes to the formating, if that's the standard sure I'll change it, but I don't get what the "=%" is referencing to. End of response to Kp's first message. And as for the posts following that referenced to my level of understanding. You're right, but it's ok to not understand what's bad it to stay confused. We all have our low moments in everything, but we all learn and progress. One day I hope to be a help to those who need guidance, thanks for yours. | March 5, 2005, 6:46 AM |
Kp | Unfortunately, there is no single standard on formatting. However, I don't think you're following any of them atm. :) =% would normalize your formatting if you were using Vim as your editor. | March 5, 2005, 5:57 PM |
Gnathonic | [quote author=Kp link=topic=10760.msg102584#msg102584 date=1110045464] Unfortunately, there is no single standard on formatting.[/quote] But there are some more commonly accepted bits of formating that are done, or am I wrong on this part also. [quote author=Kp link=topic=10760.msg102584#msg102584 date=1110045464] However, I don't think you're following any of them atm. :)[/quote] On the last post I made of code I learned it from, or the one before. On the on before when I copied it across it dropped some of the spacing, tabing, indenting, or whatever you want to call it. But on the code I learned it from it copied right. I would have edited the other one but couldn't see the indenting correctly when I went to edit the post. [quote author=Kp link=topic=10760.msg102584#msg102584 date=1110045464] =% would normalize your formatting if you were using Vim as your editor. [/quote] Nope, I'm not using Vim, just Microsoft's VC++... Can that use it and if so, how would one use it? | March 5, 2005, 6:45 PM |
Arta | [quote author=SoR-Mephisto link=topic=10760.msg102566#msg102566 date=1110003951] Isn't foo actually a variable being a pointer to the function? I'm under the impression that all function names are actually pointers, and from your example a pointer is a variable (in most cases). [/quote] It's certainly not a variable - it's a function identifier - but I suppose it could be considered a const pointer to the function. It can certainly be used that way. I'm not sure of the internal construction of this though: can someone clarify? Anyone got the grammar handy? :P | March 5, 2005, 7:39 PM |
gameschild | just reading through and not sure but: FARPROC funcPtr = (FARPROC)functionName; should give you a pointer to that function so i think in a way the function name is a pointer | March 16, 2005, 10:01 AM |