Jump to content
  • Advertisement
Sign in to follow this  
JohnnyCode

uncertain about C# cache

This topic is 2076 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

 

I have a question (few of them) towards cache friendlyness towards C#.

Suppose I have a member function in a class that does not access only members of the class, but also uses members of another class-B.

I pass this class B pointer to the function and make it a local variable of the function, but, accessing members over this B instance would make it pointless. So my idea is to move entire copy of the class to the local variable, but, how? Should I even? -I use the class B members a lot in the function

 

Another question is, that, if I write a class with higher typed members that gets heavily used in the class, but those members are pointers, how would I make them member instances instead? The c++ equvalent:

 

class SM {

TcpClient m_pClient; // not TcpClient* m_pClient;

}

 

C# creates instead:

 

class SM

{

TcpClient* m_pClient=(constructor routine-fragmented in heap)

}

 

How would I force C# to do the uper given C++ routine?

 

Also, I have heard C# Memory manager moves objects in RAM, is it true?

 

Thanks

Share this post


Link to post
Share on other sites
Advertisement
You can't pass objects around by value in C# unless they are structs or plain old data types, like int or float. What you have to do is create a copy of the object and keep a reference to the copy instead of the original. You can look up the IClobeable interface on MSDN for more info.

Also, yes, in C# objects will move around in memory when garbage collection happens. This will be transparent to you, as the memory manager will fix up all your pointers for you.

Share this post


Link to post
Share on other sites

I understand that you are wanting to make a local copy of some instance data so as to not have to fetch it through a pointer.

 

If that's what you need, I think you might be trying to over-optimize in a way that isn't likely to provide any benefit.  Do you have some performance issue you are addressing?

 

All accesses are through a pointer (within a register), except for values temporarily stored in a register. Your local variables go on the stack and are access as an offset to a pointer that is held in a register.   This is no different than accessing them through an instance pointer.

 

As soon as you access something in a class, [at least] 64-bytes of data (L1 cache line) worth of yearby data are cached and subsequent accesses occur from this [extremely fast] cache.  This is identical to what happens with your local variables.

 

In most cases, worrying about cache is unecessary, the exception being access to larger amounts of data, whereby you cause cache-lines to be filled, but don't use all the data, only to return and re-cache the SAME data later to access a different part of it.

Share this post


Link to post
Share on other sites

TcpClient is a strange example to use when asking about cache friendliness.  Almost all of the interesting operations a TcpClient can be used for will be bottlenecked by the network and not by the cache... 10-Gigabit ethernet would reach a theoretical maximum of about a gigabyte of data per second, and even system RAM has at least that much bandwidth (on a typical desktop PC built within the past 5 years, anyway - or in fact any device capable of usefully supporting 10-Gigabit network connections).

 

However, if you're thinking about cache-friendly data structures for high-performance data manipulation, you should always consider whether your data could be fit into arrays and structs rather than using nested objects (aka "recursive data structures").  One big array will be more cache friendly than anything else, and structs inside arrays will result in all data being contiguous in memory.  Arrays of reference types will result in an array of pointers, where each pointer might point to anywhere in memory (though in practice typical GC implementations will likely relocate them so that they come shortly after the array and be relatively contiguous, especially if you initialized the individual objects immediately after the array).

 

As far as I can tell (I have not yet viewed raw memory in this case), C# also has a small limitation with arrays/structs compared to C or C++; C# arrays are reference types, so if you have a struct-of-arrays, each array may end up in non-contiguous locations in RAM.  So there is no advantage to struct-of-arrays over class-containing-arrays.  There may be some way to construct C/C++ style struct-of-arrays using nonstandard techniques that I haven't encountered yet.

 

There's also nothing you can do for pre-written classes like TcpClient - they are reference types and cannot be changed to value types.

Edited by Nypyren

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!