Running Multiple Optimizations Simultaneously
Author: Panache
Creation Date: 11/16/2018 11:47 PM
profile picture

Panache

#1
I spend a lot of time running optimizations, so I’m always looking for a way to do it faster. I decided to spend some time benchmarking various methods for running optimizations to have some data to determine the fastest way to run a lot of optimizations.

The first thing I tested was the difference in the elapsed time to complete an optimization with various numbers of optimizations running simultaneously.



It took about 1.6 times longer to complete each optimization when I ran four optimizations simultaneously than it did if I just ran one at a time. That means I will get done running four optimizations a lot faster if I run them all simultaneously than if I run them one at a time.

The pattern didn’t continue when I ran eight simultaneously. It took about 2.1 times longer to complete each optimization when I ran eight optimizations simultaneously than it did when I ran four simultaneously. Therefore, I will get done running eight optimizations a little faster if I run them four at a time. This assumes that I will be able to start the next optimization as soon as one finishes. If I am away from my computer for an extended period of time (I do like to sleep at night), it is probably still faster to run eight optimizations simultaneously.

But, I wasn’t done yet. “.NET's garbage collector manages the allocation and release of memory for your application.” https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/index “By default, the runtime uses concurrent or background garbage collection, which is optimized for latency. If your application involves heavy user interaction [Panache - think video games], leave concurrent garbage collection enabled to minimize the application's pause time to perform garbage collection. If you set the enabled attribute of the <gcConcurrent> element to false, the runtime uses non-concurrent garbage collection, which is optimized for throughput.” https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcconcurrent-element

I re-ran all the optimizations with background garbage collection disabled.



When I ran only one optimization at a time, disabling background garbage collection made absolutely no difference. When I ran four optimizations simultaneously, the elapsed time for each optimization was about 10% less with background garbage collection disabled. When I ran eight optimizations simultaneously, the elapsed time was about 20% less. That changed the calculus about whether to run four or eight optimizations simultaneously. With background garbage collection disabled, the elapsed time for each optimization was only about 1.8 times as long when I ran eight optimizations simultaneously as when I ran four optimizations simultaneously.

So, if more is better, why stop at eight? In my experience, the optimizers become unstable with more than eight optimizations running simultaneously. This shows up as having a Profit/Bar of NaN for one or more strategy parameter combinations, which should have resulted in trading, ie. if you ran the strategy with those combinations, the Performance tab doesn’t show all zeros. The easiest way to find this is to sort by Profit/Bar first, and NaN will be at the top of the list.

These benchmarks were performed on a desktop computer with 16GM of memory and a pretty fast Intel i7 processor. The i7 processor has four physical cores and eight logical cores, hence my choice of the number of simultaneous optimizations to benchmark. The computer was not running any other programs, other than anti-virus and other “background” applications.

The optimizations were all of the same strategy with different parameters which resulted in various completion times. Multiple optimizations were performed by running one instance of Wealth-Lab Pro and one or more instances of the strategy within that single instance of Wealth-Lab Pro. In order to provide meaningful results for the tests of multiple optimizations, as soon as one optimization finished, it was checked to make sure it hadn’t become unstable and then restarted, so the computer was almost constantly running the specified number of optimizations simultaneously.

If you want to experiment with disabling background garbage collection, go to C:\Program Files\Fidelity Investments\Wealth-Lab Pro 6. Right click on WealthLabPro.exe.config, select copy, and paste the file back into the same directory. That way, if you want to go back to the original configuration, you can just delete the modified file and rename the copy.

Next, right click on the original WealthLabPro.exe.config and open it with Visual Studio (or WordPad if you don’t have Visual Studio). Find
CODE:
Please log in to see this code.

and insert the following on a new line after that
CODE:
Please log in to see this code.
(Eugene, I don’t fully understand all the values in this line, so if you have any suggestions about how it should be changed, please chime in.)

Then scroll down to find
CODE:
Please log in to see this code.

After that, insert the following new lines:
CODE:
Please log in to see this code.


Save the file and restart Wealth-Lab.
profile picture

Eugene

#2
Kurt, thanks for sharing this.

I don't quite get the notion of inserting the runtime section inside the "URL_REQUESTS" section (which appears WLP specific). The WealthLabDev.exe.config does not contain such section at all. So if we follow the MSDN we'd take these steps:

1. Open WealthLabPro.exe.config or WealthLabDev.exe.config in an XML-capable editor (I prefer Notepad+ but you could use Programmers Notepad, VS Code etc.) which runs with admin rights (start the editor by right-click and choose "Run as admin").

2. Straight on top of the "appSettings" section i.e. before the <appSettings>, insert this block:

CODE:
Please log in to see this code.


3. Save the file and restart Wealth-Lab.

For some reason, adding the block on top of the <configSections> crashes WLD so I put it before the next block (i.e. <appSettings>). Note that the .config files are somewhat different for WLP and WLD.
profile picture

Panache

#3
QUOTE:
I don't quite get the notion of inserting the runtime section inside the "URL_REQUESTS" section

I'm sorry my instructions weren't clear. I created a new section for runtime, and then inserted that outside of the URL_REQUESTS section. However, your way is obviously simpler.

I finally figured out how to insert an image into a post, so I made #1 look prettier.
profile picture

superticker

#4
If you're going to make concurrent garbage collection work optimally, then you need to devote one core to it exclusively. So if you have a four core processor, run three simultaneous optimizations with concurrent garbage collection. That should give you the best outcome while still being miserly on memory.

So with a four core processor, I'm guessing running three optimizations with concurrent garbage collection will produce comparable times to running four optimizations without concurrent garbage collection. Now the latter might give you more throughput, but that's a separate issue.

You could also try comparing 7 optimizations with concurrent garbage collections to running 8 optimizations without. I'm not sure what you'll get there.

---
All this is going to depend on how much garbage your strategy generates in the first place. Always code to minimize memory usage and maximize the Principle of Locality of your code. That should minimize garbage created and maximize processor L2 & L3 cache hits.
profile picture

Eugene

#5
Well said.
profile picture

Domintia-Carlos

#6
If you need faster simulations and optimizations, please, take a look at BTUtils for Wealth-Lab . Up to hundreds of times faster optimizations!


Carlos pérez
https://www.domintia.com
This website uses cookies to improve your experience. We'll assume you're ok with that, but you can opt-out if you wish (Read more).