Errors, bugs, questions - page 2160

 
Andrey Khatimlianskii:

From MQ's point of view, apparently correctly. As always, decided for us what is more convenient.

Forum on trading, automated trading systems and testing trading strategies

There are no messages in the profile.

Renat Fatkhullin, 2018.03.08 10:31

Removed temporarily to reduce the amount of functionality working in compatibility mode.

We'll add new features as soon as the migration process is complete.

This is a new very large and feature rich system.


New chat rooms are being introduced.

 
Andrey Khatimlianskii:

From MQ's point of view, apparently correctly. As always, decided for us how to be more comfortable.

Moving on to the level of telepathic... )))))

 

Unclear bug in the main indicator. Appears only on timeframes below H1, and only at terminal startup. Text of error "S-v5 (EURUSD,M10) array out of range in 'S-v5.mq5' (211,54)" . Drawing is correct, but in reverse order, though time series flag is set for all buffers.

The composition of the template - the main indicator (#1) (where the error occurs), additional indicator (#2) (combination of several handles of the main indicator with different parameters (timeframe), indicator (#3) that displays arrows in the main chart on the signals from the indicator #1), indicator (#4) that displays arrows in the main chart on the signals from the indicator #2.

Switching timeframe, re-application of the template, if you remove any 2 indicators from 2 to 4 or only at number 1, the output of a new symbol from the market overview and application of this template - the error is not reproduced and rendering of all indicators is correct.

 

Compilation error

#import "Test1.ex5"
       void f1();
#import "Test2.dll"
       void f2();
#import
typedef void (*fn)();
void OnStart()
{
    fn fn1 =        f1; //нормально
    fn fn2 =        f2; //Error: 'f2' - pointer to this function type is not supported yet
    fn fn3 = Test2::f2; //нормально
}
 

The error message does not allow the cause to be understood in the extensive code

struct A {
    void f( int    ) {}
    void g( int fn ) { f( fn ); } //Error: ')' - unexpected token ???
};
typedef void (*fn)();

below is clear

struct A {
    void f( int    ) {}
    void g( int fn ) { f( fn ); } //Error: 'fn' - identifier already used
};
struct fn {};
 

No error message

typedef void (*fn)();
void f( int i ) { Print( __FUNCTION__, ":", i ); }
void OnStart()
{
    f( fn() );
}

moreover, it is running and there is even a result (!)

In this variant:

typedef int (*fn)();
void OnStart() { Print( fn() ); }

no jump to the error line (by Enter)


 

Compilation error

    void g(  int ) {}
    void g( uint ) {}
#import "Test.ex5"
    void f(  int );
    void f( uint );
#import
typedef void (*fn1)(  int );
typedef void (*fn2)( uint );
void OnStart()
{
    fn1 g1 = g; /*нормально и результат*/ g1( 1 ); //совпадает с ожидаемым
    fn2 g2 = g; /*нормально и результат*/ g2( 1 ); //совпадает с ожидаемым
    fn1 f1 = f; //Error: 'f' - cannot resolve function address
    fn2 f2 = f; /*нормально и результат*/ f2( 1 ); //совпадает с ожидаемым
                                                   //при наличии Test.ex5
}
 

In an attempt to speed things up when I was creating this example, I ran into one oddity completely by accident, which I just put on the shelf.

And now, when I tried to deal with this oddity, I got even more confused.

So, in the calculation I use the square root function sqrt(), which I decided to bypass by creating a double array.

Since I always take the square root from integers, creating an array looks like this:

   double SQRT[];
   int ss=Width*Width+Height*Height;
   ArrayResize(SQRT,ss);
   for(double w=0;w<ss;w++) SQRT[(int)w]=sqrt(w);

It is logical to suppose that reading from the array SQRT[x] is faster than using the sqrt(x) function.
And this is confirmed by the check code:

   double Sum1=0,Sum2=0;
   ulong t=GetMicrosecondCount();
   for(int i=0;i<ss;i++) Sum1+=sqrt(double(i));   // Находим сумму квадратных корней всех целых чисел от 0 до ss
   t=GetMicrosecondCount()-t;
   Print("Время на сумму "+IntegerToString(ss)+" значений функций = "+IntegerToString(t)+" мкс, Сумма = "+DoubleToString(Sum1));
   t=GetMicrosecondCount();
   for(int i=0;i<ss;i++) Sum2+=SQRT[(int)(i)];    // Находим сумму квадратных корней всех целых чисел от 0 до ss через сложение элементов массива SQRT[]
   t=GetMicrosecondCount()-t;
   Print("Время на сумму "+IntegerToString(ss)+" значений массива = "+IntegerToString(t)+" мкс, Сумма = "+DoubleToString(Sum2));

the result shows a speed gain of ~1.5 times:

But when I replace the sqrt() function in the code with reading the array elements SQRT[], instead of speeding up, I get terrible lags.

Reading an item from the SQRT[] array takes many times, perhaps even an order of magnitude longer than running sqrt().

And I don't understand where speed leak occurs. The check code above tells you otherwise.

We can suppose that the compiler accesses a large array in some strange way and seems to "forget" about it at each loop turn and performs its own service indexing each time.

But this is either a logical or a strategic compiler bug. And you should obviously do something about it because this speed leak is very significant and difficult to detect because it's not so obvious.

I am attaching the script code to demonstrate this oddity.

The default run (arr=false) calculates sqrt(), but when you change arr to true, the square root value is taken from the array.

WHAT'S WRONG? WHY IS IT SLOW?

Files:
Swirl.mq5  11 kb
 
Nikolai Semko:

In an attempt to speed things up, when creating this example, I ran into one oddity completely by accident, which I just shelved.


It is logical to assume that reading from the array SQRT[x] is faster than taking sqrt(x).

From a dynamic array, it's not a fact.

Moreover, taking of the root is already in place at the level of SQRTSD processor's command. That is, you cannot beat the processor's implementation using the notorious cost of access in a dynamic array.


And this is confirmed by the verification code:

the result shows a speed gain of ~1.5 times:

I doubt that it is confirmed.

The code of this kind is like something out of a textbook on loop optimization. The code optimizer might make a sweet out of it because it is a very simple case:

   for(int i=0;i<ss;i++) 
      Sum2+=SQRT[i];

That is, the performance measurement in the case of application of the deliberately perfectly optimised cases needs to be clearly related to the goals of the test.

The test in this case is wrong.

It takes many times, perhaps even an order of magnitude longer to read an item from the arraya SQRT[] than to perform the sqrt() function.

And I don't understand where the speed leakage occurs. After all, the above test code says otherwise.

Without seeing the final assembler code, I'm leaning towards:

  1. sqrt is actually fast (we have a very efficient generator to native code, sqrt turns into pure SQRTSD)
  2. the checker code is too simple and compensates for delays by optimizing


Let's check the entire code carefully. It is interesting to find out what is the real reason.

SQRTSD — Compute Square Root of Scalar Double-Precision Floating-Point Value
  • www.felixcloutier.com
Computes square root of the low double-precision floating-point value in xmm3/m64 and stores the results in xmm1 under writemask k1. Also, upper double-precision floating-point value (bits[127:64]) from xmm2 is copied to xmm1[127:64].
 
Renat Fatkhullin:

From a dynamic array, not a fact.


Without seeing the final assembler code, I'm leaning towards:

  1. sqrt is actually fast (we have a very efficient generator in native code, sqrt turns into pure SQRTSD)
  2. checker code is too simple and compensates for delays by optimizing

Tried a static array - same thing.

As fast as sqrt is, I find it hard to believe that this function can be 10 times faster than just reading an array element.

Moreover, if in my example the canvas size is reduced, say 50x50 (there is an input parameter Size for this, you need to set 50 instead of 0),

and the array will be much smaller (5000 elements), the speed picture changes dramatically. There is no such a strong contrast anymore.

But I don't understand: does the array's size affect the speed of accessing its items?

Perhaps you are right about the simplicity of the check code.

I tried to make it a bit more complicated and the result is completely different:

for(int i=0;i<ss;i++) Sum1+=i*sqrt(double(i));
....
for(int i=0;i<ss;i++) Sum2+=i* SQRT[(int)(i)];