Features of the mql5 language, subtleties and tricks - page 276
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Ah, the days of assembly language programming.... I used to calculate speed by knowing the number of clock cycles of each instruction. I had to, when in the 80s I wrote a driver for our laboratory audio card and a speech synthesiser for GTS.
And on the matter - if you calculate the number of mat. operations and estimate the speed of each type ( * / + - - )?
Nowadays you won't see it and you won't calculate it...well, or you have to study convectors, register-aliasing, caches and so on.
It used to be simple: here is a processor, it executes commands one by one. Total time = sum of all. Now it sucks a bunch of commands into a cache, arranges them into chains, plans operations and executes all this at the same time. roughly like this
Nowadays you won't see it and you won't calculate it...well, or you have to study convectors, register-aliasing, caches and so on.
It used to be simple: here is a processor, it executes commands one by one. Total time = sum of all. Now it sucks a bunch of commands into a cache, arranges them into chains, plans operations and executes all this at the same time. roughly like this
My observations about the results:
This code executes fast because:
* it uses least possible number of divisions and modulo (takes a lot of processor cycles).
* most variables are 32-bit, unsigned types.
* only one branching (conditionasl operator), so the cpu pipeline is not flushed out frequently.
* The code benefits from AVX2 instruction set which support FMA (fused multiply addition), the code mostly uses * and +
See on the contrast why this code is slower:
no branching, but with a lot of div/mods.
One trick I learned recently about datetime type -> casting datetime variables to ulong (or even better to uint) makes a huge speed-up with datetime variables (depending on the surrounding code).
Here in this code, the second version of TimeHour() is faster:
that's why fxsaber found slow-down in TimeToJulian when hh:mm:ss are calculated. Because I forgot to cast to ulong :-)
Utilizing the cpu branch predictor may benefit micro-optimization, see here: https://stackoverflow.com/a/11227902
Although the isleap check is eliminated from the main instruction path, it is still get executed in 84% of times. (1 - 59/365). That's why there was no big improvement here. The cpu predicts the right branch 84% of times at (doy < 59) ?, but it finds another branch there !(year & 3), so the instruction pipeline has to flushed and re-filled again.
Finally, I think this is the max we can optimize, any of the first 4 functions are within an accepted 10% variability, and any of them is even faster than MQL's built-in TimeToStruct 4-5 times.
IMHO these functions may be optimized more by adding a cache, much like the built-in TimeToStruct function https://www.mql5.com/ru/forum/170952/page274#comment_55238816
TimeToJulian may be less optimized for the job.
The speed-up factors for the sub-functions (TimeYear, TimeDayOfWeek, etc..) to extract time components such as yyyy/mm/dd hh:mm:ss are within 10-20 times faster than TimeToStruct().
High performance code with complex for loops to scan the quotes history searching for certain patterns or bars (begin of trading weeks, doing other statistics) will benefit from these optimizations.
Regular code for a trading robot may also benefit but to a lesser extent.
On the other side of the coin, composing datetime variables from time components (yyyy/mm/dd hh:mm:ss) using the custom CreateDateTime() as an alternative to StructToTime will gain > 30x times speed-ups.
Composing datetime variables is really slow on the MT5 platform and needs some consideration from the devs.
For all the cached versions, I suggest this fix for a possible bug that could happen.
Initially, when the function are called repeatedly with times on 1970/1/1, it returns 000/00/00 for the year, month date fields.
-1 will fix this bug, so the returned dates are correctly 1970/1/1.
Some very little more optimized version:
Results:
Some very little more optimized version:
Results:
A slightly more optimised version:
Wow! The first version, consistently the best on all processors (x86/AVX/AVX2).
Just probably should make a script to test for correctness of all algorithms. It's simple, IMHO. In a date loop compare all the results of calculations with the built-in function.
Great Dominik, you were able to break the 5 nanoseconds record in this video https://youtu.be/0s9F4QWAl-E?si=ZzdFCrFtU8Ean2NJ&t=590
Some very little more optimized version:
Results:
AVX2 slower than X64 ? It's strange.