• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
sebastiansylvan

[.net] memset?

20 posts in this topic

Hey! Is there a way to replicate the functionality of "memset" in C#? I'm doing some unsafe hacking and need to zero out a block of memory very quickly. Thanks!
0

Share this post


Link to post
Share on other sites
Not going to happen.

People don't use C# for its runtime performance.
0

Share this post


Link to post
Share on other sites
Well there are pointers and etc. to get runtime performance where it's needed, so I figured that if I'm allowed to work with raw buffers, maybe there exists a fast way to zero a buffer.
0

Share this post


Link to post
Share on other sites
Maybe you can do it with p/invoke, see the end of this discussion:
http://www.gamedev.net/community/forums/topic.asp?whichpage=1&pagesize=25&topic_id=389036

("People don't use C# for its runtime performance." Hmm. C#'s killer feature isn't speed, but that doesn't mean we shouldn't look for ways to optimize.)
0

Share this post


Link to post
Share on other sites
Unless there's a specific .net framework function do do it, you could just use memset.


[DllImport("msvcrt.dll")]
private static unsafe extern void memset(int[] dest, int c, int count);

private void button1_Click(object sender, EventArgs e)
{
int[] x = new int[10];
for (int i = 0; i < x.Length; ++i) x[i] = 10;
unsafe
{
memset(x, 0, 4);
}
label1.Text = x[0].ToString();
}


0

Share this post


Link to post
Share on other sites
Thanks, I'll use the standard memset for now. Does that dll come with windows or .net or both? It kinda sucks that it won't be portable though.

Regarding the speed of C#, I must say that so far I'm quite impressed. I'm writing a software renderer and although it's not a completely a fair comparison I think it fares pretty well against Quake. Most of the time is spent in the rasterizer for both engines (>90%) so testing by just looking at a wall, filling the screen, I get that quake is about 3x faster than my version. But quake gets at least a factor of two speedup by using an optimized assembler version of the inner rasterizer loop (basically utilizing that pentium processors and later can do floating point adds in parallell if you don't fetch the results right away), and quake also uses a subdivided affine perspective correction (only computing the perspective correction every 8 pixels, IIRC), whereas my version does a completely accurate perspective correction. Also I use 32 bit textures and frame-buffer so that might work in quake's favour as well. Overall I think C# is very close to C in speed for this application (which is a rather extreme case for the 80/20 rule, admittedly), most of the speed difference is due to me, not C#.

I wrote it in C# to test out the concepts for fun, never really thinking that it would be this fast, but I've been quite impressed so far! Everything is written in the most naive and obvious way and it's still very fast compared to one of the fastest rasterizers around.
0

Share this post


Link to post
Share on other sites
I'd expect the overhead of the p/invoke is going to negate any speed increase you may see (although I'm really not sure you would actually see any speed up). This is especially true if you don't tag the declatation with:

[System.Security.SuppressUnmanagedCodeSecurity]

if you don't do this, .net will do a stack check after each call to make sure the stack is still intact (well, that is my understanding of what this supresses). Needless to say, it'd be *much* slower without this in your case.

It's impressive you the speed you claim for your ray tracer. I've written a couple of little ray tracers before in C# and C++ at the same time (for comparison) and it ended up that C# managed the complex ray tracer better, while C++ managed the linear time one better (as expected). It was still interesting however. Surprisingly, the linear ray tracer with C++ floating point accuracy optimisations off was almost exactly the same speed as the C# one. I can't remember if this was .net 1.1 or 2.0 though.
0

Share this post


Link to post
Share on other sites
Well it wasn't a ray-tracer, it was a rasterizer.
I've been pleasantly surprised about many things in C#, speed-wise. For instance, I was sure that garbage collection was slower than manual memory management, but if you benchmark it you'll see that heap allocation is about twenty times faster in a garbage collected language. This really shouldn't be surprising if you know how garbage collection works (allocation in C# is a pointer incrementation with a check, roughly five instructions, whereas in C++ it's a huge mess of best-fit/first-fit algorithms, roughly a hundred instructions) but somehow I had bought in to the myth of the slowness of garbage collection without benchmarking it (bad programmer, BAAAD programmer!!!).
At any rate, C++ still gains a lot due to less runtime checks (out-of-bounds, overflow etc. -- which you can turn off!) and the fact that C++ programs typically allocate on the stack more often, but it's surprising that C# programs fare so incredibly well in comparison!

About the memset, it turns out that using an unchecked loop and setting the memory one word at a time (rather than one byte at a time as in memset?) is a little bit faster than using P/Invoke.
0

Share this post


Link to post
Share on other sites
fantastic.
It will be interesting to see what you have created. *hint hint* [wink]

Looking back I should have proof read my previous post :-) *sigh*
0

Share this post


Link to post
Share on other sites
Quote:
Original post by sebastiansylvan
But quake gets at least a factor of two speedup by using an optimized assembler version of the inner rasterizer loop (basically utilizing that pentium processors and later can do floating point adds in parallell if you don't fetch the results right away)

Assembly isn't required for that. The compiler (includnig the C# compiler) and CPU will both attempt to schedule the instructions to make this possible.
0

Share this post


Link to post
Share on other sites
Well there's a whole lot more to the assembler optimizations you could do that the compiler has no chance of figuring out (I sort of lied/simplified :-))

Check out: http://www.d6.com/users/checker/misctech.htm

Particularly the last one, and the extra article on floating point optimizations.

Needless to say, there's a whole slew of extra performance to be gained by using clever low-level optimizations which I have not done at all so far. A ~3x performance difference in that light really is quite surprising.
0

Share this post


Link to post
Share on other sites
I should reiterate that the 3x number really is just a fifteen second ballpark-benchmark. It may be 2x it may be 5x, but it's not 10x (which would've been about what I had expected).
0

Share this post


Link to post
Share on other sites
for zero'ing memory there are methods in Marshal to do that (well from memory there are) and also Array.Clear(...), etc.
0

Share this post


Link to post
Share on other sites
I have a trouble with importing memset... I do exactly what is written in the code above:

impoting:

class ExtrnCalls
{
[DllImport("msvcrt")]
public static unsafe extern void memset(int[] dest, int c, int count);
}


and using memset:


Random rnd = new Random(1);
int[] x = new int[4];
for (int i = 0; i < x.Length; i++)
{
x[i] = rnd.Next();
}

ExtrnCalls.memset(x, 0, x.Length);

foreach (int i in x)
Console.WriteLine(i);


and I get that result:

0
237820880
1002897798
1657007234

instead of four zeroes.

What is wrong?
0

Share this post


Link to post
Share on other sites
The count parameter is wrong, it should be the amount of bytes (not array elements) you want to change. Since int is four bytes, you only set the first element in the array.

Correct is:


ExtrnCalls.memset(x, 0, x.Length * Marshal.SizeOf(typeof(int)));
0

Share this post


Link to post
Share on other sites
Quote:
Original post by unbird
The count parameter is wrong, it should be the amount of bytes (not array elements) you want to change. Since int is four bytes, you only set the first element in the array.

Correct is:


ExtrnCalls.memset(x, 0, x.Length * Marshal.SizeOf(typeof(int)));


Ok. But if I change "character to set" from zero to 254 I get this:


int[] x = new int[4];
ExtrnCalls.memset(x, 254, x.Length * 4);

Out:
-16843010
-16843010
-16843010
-16843010


for 1 I get this:

16843009 (=1000000010000000100000001)
16843009 (=1000000010000000100000001)
16843009 (=1000000010000000100000001)
16843009 (=1000000010000000100000001)

as follows from the result memset is working only with bytes, but I remember that in C it was possible to set int's.
0

Share this post


Link to post
Share on other sites
Quote:
...memset is working only with bytes...


It is in fact so, and according to the Windows SDK doc I don't find anything for your purpose.

If you want to support any type, a generic method might be useful.


public static void SetAll<T>(T[] array, T value)
{
for (int i = 0; i < array.Length; i++)
array[i] = value;
}




As already stated, I also think you gain little speed, if at all. You really need big arrays before you experience a gain.
0

Share this post


Link to post
Share on other sites
I don't think your dllimport is correct. AFAIK, size_t translates to IntPtr, not int (otherwise you'll corrupt your stack on 64bit runtimes). Try this:

// C definition: void * memset ( void * ptr, int value, size_t num );

[DllImport("msvcrt")]
public static extern IntPtr memset(int[] dest, int c, IntPtr count);

// or this
[DllImport("msvcrt")]
public static unsafe extern void* memset(void* dest, int c, IntPtr count);






Usage:

int[] x = new int[4];
memset(x, 0, new IntPtr(4)); // first version

unsafe {
fixed (int* x_ptr = x) {
memset((void*)x_ptr, 0, new IntPtr(4)); // second version
}
}





This can be made cross-platform using a dllmap to map msvcrt to the correct shared object on Linux, OSX or any other platform.
0

Share this post


Link to post
Share on other sites
Quote:
Original post by unbird
Quote:
...memset is working only with bytes...


It is in fact so, and according to the Windows SDK doc I don't find anything for your purpose.

If you want to support any type, a generic method might be useful.

*** Source Snippet Removed ***

As already stated, I also think you gain little speed, if at all. You really need big arrays before you experience a gain.


Actually, the speed gain is far from trivial. Try benchmarking your loop as-is and then unrolled at steps of 16. The latter will have noticeably better performance than the former.
0

Share this post


Link to post
Share on other sites
I've wrote the fuction which fills memory by 4 bytes in C++ and imported it. But performance still leaves much to be desired.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0