Skip to main content
GameDev.net gamedev.net
🔒 Locked

Better method.

Started by -aaronljx- Feb 16, 2009 at 2:55 AM 5 replies 900+ views
Original Post
-aaronljx-
-aaronljx-
I'm writing a code to copy a source buffer to a destination buffer. Initially i use a nested loop to copy the buffer by individually assigning every element into the destination buffer. I figure out that memcpy might be more efficient and faster but I am not sure, which method is better? If I use memcpy, I'll memcpy row by row. Code: for ( Row = Y; s_Y < nRows; ++Row, ++s_Y ) { for ( Col = X, s_X = 0; s_X < nCols; ++Col, ++s_X ) { Dest[Row][Col].Attributes = Source[s_Y][s_X].Attributes; Dest[Row][Col].Char.AsciiChar = Source[s_Y][s_X].Char.AsciiChar; } } // Better method? More efficient? for ( Row = Y, s_Y = 0; s_Y < nRows; ++Row, ++s_Y ) memcpy( &Dest[Row][X], Source[s_Y], nCols * sizeof( CHAR_INFO ) );
scratt
scratt
Both methods have overhead, and depending on the volume of data moved it may be that which dictates the speed of your routine and not the actual movement of data.

memcpy should be optimized by your compiler to be the most efficient way to move whatever size of data you specify based on the capabilities of your CPU.
In theory!

I did not look closely at your implementation, but.. just be careful if the copied data overlaps. You should avoid this if you are worried about speed in any case. But if you can't then memmove should automatically deal with that.

The absolute best case would be to double buffer, or arrange your data in some way so that you can memcpy in one chunk. But again this may not apply to your implementation.

Removing the loop in either case is going to speed things up if your compiler is not unrolling loops.

Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
-aaronljx-
-aaronljx-
Overlap as in? You mean like data from the destination buffer overwrites source buffer? How do I double buffer it? Sorry I am just a beginner but it would be helpful if there are articles on this sort of issue. thanks.
scratt
scratt
Sorry. I probably just caused you needless worry... Just trying to be comprehensive with the info,

With memcpy if you are copying say 100 bytes from address 10 to say address 20 then the first 10 bytes will be copied ok, but the last 90 will most likely be garbage as memcpy is getting data from the same place as it is writing to. That's all.

memmove copies the source to a buffer and then back to the destination. Hence being slower but having no problem with overlapping data.

Depending on how your rows and columns are setup you may find that you get that problem with memcpy.

In effect you are already double buffering as you have two arrays I think. All I would suggest is looking at your algorithm and seeing if it's possible to work on one buffer and then just copy the whole thing in one go. But I don't know what you are doing, so it's just an offhand comment.

Basically the less looping, and the larger the chunks you can move data in, you are always going to benefit.
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
MortusMaximus
MortusMaximus
If memcpy is the most efficient method, then why not just copy the entire array with one call by treating both as a 1D array?

memcpy( &Dest, Source, nCols * nRows * sizeof( CHAR_INFO ) );

Personally I try to avoid such optimizations, because it really cuts down on readability, unless you're working on something like matrix multiplication.



Also, in the code you provided, why do you have Dest[Row][X] when source is only Source[s_Y]?
Check out the first gameplay video from my javascript/PHP RTS game
DevFred
DevFred
Are Dest and Source true two-dimensional arrays or arrays of pointers?

Also, which language are you using?
-aaronljx-
-aaronljx-
I am using C and yeah it's a 2d array.

Basically why it is &Dest[Row][X] and Source[s_Y] because Dest is a bigger array, the actual screen buffer while source is only the buffer of an object. Therefore to draw object to the screen, i copy the whole object buffer into the screen's buffer at desired location ( x, y). Implementation wise, both buffers are actually 1D array, just that i use another set of array of pointers as the interface to access the buffer. Since I am copying the whole object, I don't have to worry about its x as it is taken care of when nCols * sizeof(CHAR_INFO) is passed. But for the the destination buffer, x is taken into consideration as I would be drawing at desired location of x and y therefore it is then &Dest[Row][x].

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.