|
-
Apr 29th, 2024, 02:27 PM
#4
Re: Core Affinity
I overlooked the WhenAll, but now that I think about it, it probably isn't ideal for me. I'm using WaitAll because there isn't anything useful that can be done until all the Tasks have been completed. I don't believe that the Task Parallel Library would be the way to go with this, but I'll have to look at that again.
I really don't want to redesign to go for a much more efficient route. I know what that would be, but all I'd gain would be speed, and not a game-changing amount of that, but the interface would be far worse. The more modest type of scenario I have might not impact the interface any, so boosting the speed of it would be tolerable...maybe.
How I'm launching the tasks is just putting them all into an array of Task with:
tskList(x) = Task.Factory.StartNew(calcAction, x)
and once that has been fully populated, I WaitAll on the task array.
All of this is done in a backgroundworker anyways, such that the UI is free. I can barely time the performance. With or without the tasks, it's ripping through the generations. I originally wrote this in VB6 with a long running loop wrapping a DoEvents to keep the UI active while all the evolution stuff was going on. That would progress at a stately rate of a few generations a second, and the total run could take a few days. I re-wrote into VS2003, and apparently brought it somewhat up to date with FW2.0 in VS2005, though I clearly didn't put much effort into it. This re-write, which brought it to FW 4.7.2, got rid of the DoEvents and moves all the long running stuff into a BGW. That old version was also running on a single core Pentium of whatever speed was in vogue back around 2000. That would take at least 36 hours, and possibly many more, to get some result. On my current system, without the Tasks, the time is down to around four hours. So, even without going to any extremes, I've gotten a pretty significant boost in speed.
One result of this performance boost is that, while the Tasks are doing the most computationally expensive part of the operation, I'm still going through several hundred generations a second. They all have to access some common data, too, and the way that is done may be creating too much of a bottleneck, as I have to lock an object to supply the data. I could avoid that by either giving each Task a copy of the data, or by arranging the common data in such a fashion that the access would be thread safe without locking. I opted not to make copies, as the data could be fairly large, and it would mean making millions of copies, over time, which would end up thrashing the memory pretty badly. Since they are all just reading the data, one alternative would be to put the data into a public array and just let them read it directly, which wouldn't need any locking. That would mean some ugly organization, though, and I'm not sure I'm willing to do that.
My usual boring signature: Nothing
 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|