Poker-AI.org

Poker AI and Botting Discussion Forum
It is currently Mon Nov 13, 2023 1:45 pm

All times are UTC




Post new topic Reply to topic  [ 42 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Wed Sep 04, 2013 8:52 pm 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Per the attached image, I was wondering if anybody could offer advice on combating what appears to be an efficiency problem when dealing with very large (high memory) problems in Windows 7 Pro, VS .NET. I've disabled just about everything I can think of regarding Windows (no paging, no hibernation, disabled all unnecessary services, etc.) but the problem persists. The slow-down seems to be linearly correlated to the amount of memory used by the application, in that, the less memory used the more efficient the processing, despite all runs being well within the physical memory limits.

I'm looking for constructive suggestions, please save the "switch to linux" or "switch to C++" for somebody else.

Note: I think it has something to do with Windows memory swapping/caching, but I have no idea how to do anything about that.


Attachments:
bottleneck.jpg
bottleneck.jpg [ 248.3 KiB | Viewed 27954 times ]
Top
 Profile  
 
PostPosted: Wed Sep 04, 2013 10:38 pm 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
Is the application thread blocking? If you run 24 processes each consuming 1/24 of the total memory do you see the same problem?


Top
 Profile  
 
PostPosted: Wed Sep 04, 2013 11:53 pm 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Why would thread blocking linearly correlate with the amount of memory used? You're likely right, but I just don't understand why it matters?

I don't use any kind of sync locking. Threads are allowed to collide, etc. This isn't to say that my version of .NET isn't doing all kinds of syncing in the background. How do I make this work? Maybe the shared objects/functions in my GameTreeNode class are causing the blocking? Or, maybe the node class itself?


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 6:29 am 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
- I'm assuming this application doesn't do any IO.
- How many threads do you set up? If it's significantly more than the number of processors that might be a problem.
- I'd make sure of the diagnosis first by running some toy problems. Then post on stack overflow and give us a link.


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 7:01 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
- Only when loading/saving.
- # Threads = # Processors.

I was thinking I could use System.Runtime.Interop.Marshal to load the arrays in memory. Any suggestion on the fastest way to convert multidimensional array indices into a memory offset? :)

array[a, b, c, d, e] = a * UpperBound(0) + b * UpperBound(1) + c * UpperBound(2) + d * UpperBound(3) + e?


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 8:22 am 
Offline
Regular Member

Joined: Sun Mar 03, 2013 11:55 am
Posts: 64
Quote:
Note: I think it has something to do with Windows memory swapping/caching, but I have no idea how to do anything about that.

Less to do with Windows, more to do with hardware.

Having become a performance expert over the last year or so, I strongly suspect your problem is that reading from memory takes time.

The more memory you have in use, the lower the percentage of all the data read will be in the CPU caches, and therefore it'll be hitting the RAM more frequently.

I had a similar problem. Having done lots of profiling and tuning, I was eventually in the situation where 25% of my execution time was being spent on one simple line of code.... I eventually discovered that this was the point that the referenced object was loaded from memory, and more often that not, that object wasn't in the CPU cache.

So the good news is, there's your answer - the bad news is that doing anything about it is very very tricky.

Edit:
As an extension to that - Arrays are good as they enforce some kind of locality of memory between objects. If you keep objects that are frequently referenced in quick succession next to each other in an array this will speed things up.

When the CPU requests something from RAM, it doesn't just grab what the CPU asks for, but will grab a page of memory and put all of that in the CPU cache. Therefore if you're using an array it'll sweep a whole bunch of objects into the CPU cache, and ideally you want those objects to be useful rather that a load of stuff you couldn't care less about. So yes, arrays of data with objects accessed together adjacent to each other is the way forwards.


Last edited by OneDayItllWork on Thu Sep 05, 2013 8:34 am, edited 3 times in total.

Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 8:28 am 
Offline
Junior Member

Joined: Wed Jul 17, 2013 10:52 pm
Posts: 21
Nasher wrote:
array[a, b, c, d, e] = a * UpperBound(0) + b * UpperBound(1) + c * UpperBound(2) + d * UpperBound(3) + e?


Add some parentheses for the sums (I think):

( ( ( a * UpperBound(0) + b ) * UpperBound(1) + c ) * UpperBound(2) + d ) * UpperBound(3) + e


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 4:01 pm 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Now, fastest way to convert a double into an int64, and vice versa? :)


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 6:59 pm 
Offline
Regular Member

Joined: Sun Mar 03, 2013 11:55 am
Posts: 64
Nasher wrote:
Now, fastest way to convert a double into an int64, and vice versa? :)


(double)x

Will certainly work to convert the Int64 to a double. I'm guessing that:

(long)x

May well work and force rounding, although I'm not certain. It's a hell of a lot faster than calling Convert.ToXxx() - although doesn't work in the same way and doesn't perform the same checks.


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 8:03 pm 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
I should have stipulated, I'm not rounding. .NET marshaling only has integer read/writes. So, I need some way of "converting" a double into a long, and vice versa, while maintaining it's actual decimal value. Basically, just a direct bit mapping.


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 8:58 pm 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
http://msdn.microsoft.com/en-us/library ... erter.aspx :?:
http://msdn.microsoft.com/en-us/library/ms146627.aspx :?:
http://msdn.microsoft.com/en-us/library/ms146633.aspx :?:


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 9:17 pm 
Offline
Junior Member

Joined: Thu May 02, 2013 2:25 pm
Posts: 30
I concur with OneDay on this - it's likely that the memory bandwidth of your machine is just not enough given the number of threads running and that each thread constantly accesses different areas of memory.


Top
 Profile  
 
PostPosted: Thu Sep 05, 2013 11:26 pm 
Offline
Regular Member

Joined: Sun Mar 03, 2013 11:55 am
Posts: 64
Nasher wrote:
I should have stipulated, I'm not rounding. .NET marshaling only has integer read/writes. So, I need some way of "converting" a double into a long, and vice versa, while maintaining it's actual decimal value. Basically, just a direct bit mapping.

The quickest way is possibly to do something 'unsafe'. Or you can take a look at this:
http://msdn.microsoft.com/en-us/library ... erter.aspx


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 8:52 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Did I mention I'm using .NET 2005? :)


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:00 am 
Offline
Regular Member

Joined: Sun Mar 03, 2013 11:55 am
Posts: 64
Upgrade!

You want to be using the 4.5 framework and turn on gcAllowVeryLargeObjects to allow array > 2GB in size.


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:02 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
Right now I've got to work with what I have.


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:07 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
OneDayItllWork wrote:
When the CPU requests something from RAM, it doesn't just grab what the CPU asks for, but will grab a page of memory and put all of that in the CPU cache. Therefore if you're using an array it'll sweep a whole bunch of objects into the CPU cache, and ideally you want those objects to be useful rather that a load of stuff you couldn't care less about. So yes, arrays of data with objects accessed together adjacent to each other is the way forwards.


From a single iteration's perspective, I don't care about everything else in the array except what I need to crunch. My thought is that marshaling will prevent the program from "grabbing" the entire array into cache when I'm working on just a few elements. I don't know, though, as I've never had this problem to deal with. ;)

I'm not sure how to force useful objects to be accessed together?


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:13 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
PolarBear wrote:
I concur with OneDay on this - it's likely that the memory bandwidth of your machine is just not enough given the number of threads running and that each thread constantly accesses different areas of memory.

Like I mentioned above, it gets faster when the data arrays have smaller bounds. Given what OneDay said about the caching, this makes me think that it's tossing around the entirety of those arrays when there is work being done on just a few elements therein. I'm hoping marshaling the specific elements I need to work with will bypass that tossing.


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:15 am 
Offline
Veteran Member

Joined: Thu Feb 28, 2013 2:39 am
Posts: 437
P.S. Using the verb "tossing" wasn't an accident. ;)
http://en.wiktionary.org/wiki/tosser


Top
 Profile  
 
PostPosted: Fri Sep 06, 2013 9:30 am 
Offline
Site Admin
User avatar

Joined: Sun Feb 24, 2013 9:39 pm
Posts: 642
Doesn't the marshalling itself require the array to be moved into the cache?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 42 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group