Errori, bug, domande - pagina 2164

 
Vladimir Pastushak:

C'è poco spazio nelle descrizioni dei prodotti.

3600 caratteri sono estremamente corti per programmi grandi e seri.

Penso che molte persone saranno d'accordo con me.

Avete bisogno di non meno di 5000 - 10000 caratteri per descrivere i programmi. O almeno una scheda con il nome delle impostazioni del programma

Un moderatore può sempre chiedere di rimuovere l'acqua.

In questo momento sto scrivendo una descrizione del software, e ho usato tutti i 3600 caratteri solo per descrivere le impostazioni, ma non ho descritto nemmeno la metà delle caratteristiche...

Vladimir, hai mai comprato qualcosa? Quanto tempo hai passato a leggere il manuale?

Nessuno leggerà un libro in più volumi, e non guarderà nemmeno i video più lunghi di 3-5 minuti.
L'unica soluzione è aggiungere dei suggerimenti nell'interfaccia del programma, come fanno quasi tutti gli altri. Qualcosa come un tutorial interattivo. E le istruzioni dettagliate per gli utenti avanzati possono essere messe in un blog o sul loro sito. Chiunque lo voglia lo troverà e lo scaricherà.

 
Vladimir Pastushak:

C'è poco spazio nelle descrizioni dei prodotti.

3600 caratteri sono estremamente corti per programmi grandi e seri.

Penso che molte persone saranno d'accordo con me.

Avete bisogno di non meno di 5000 - 10000 caratteri per descrivere i programmi. O almeno una scheda con il nome delle impostazioni del programma

Un moderatore può sempre chiedere di rimuovere l'acqua.

In questo momento sto scrivendo una descrizione del programma, ho usato tutti i 3.600 caratteri solo per descrivere le impostazioni e nemmeno la metà delle caratteristiche...

Non sono d'accordo. La brevità è la sorella del talento.

"Non pensare che con le tue molte parole sarai ascoltato".

Matteo 6:7.

 
Andrey Khatimlianskii:

Vladimir, hai mai comprato qualcosa? Quanto tempo hai passato a leggere le istruzioni?

Nessuno leggerà un libro in più volumi, non guarderà nemmeno un video di 3 o 5 minuti.
C'è solo una via d'uscita: aggiungere dei suggerimenti nell'interfaccia del programma, come si fa ormai quasi ovunque. Qualcosa come un tutorial interattivo. E le istruzioni dettagliate per gli utenti avanzati possono essere messe in un blog o sul loro sito. Chiunque lo voglia lo troverà e lo scaricherà.

Quelli che non leggono e non comprano, avete comprato molti prodotti senza capire a cosa serve il prodotto?

Dovremmo allora pubblicare tutto sui blog?

 
Nikolai Semko:

Non sono d'accordo. La brevità è la sorella del talento.

"Non pensate che nella vostra verbosità sarete ascoltati".

Matteo 6:7.

Sono d'accordo, ma anche breve 3600 non è sufficiente...

 
Vladimir Pastushak:

Quelli che non leggono e non comprano, avete comprato molti prodotti senza capire a cosa serve il prodotto?

Dovremmo allora pubblicare tutto sui blog?

Capire lo scopo del prodotto dal manuale?

Che sciocchezza. Scaricherò e proverò la demo.

 
A100:

Questo codice è basato su un difetto del compilatore

Risultato: 1... Perché non 2?

Mentre il C++ segnala un errore durante la compilazione, perché entrambe le funzioni ovviamente ci stanno, e inoltre la sintassi non permette di chiamare esplicitamente la funzione (2)

Inoltre, tenendo conto delle caratteristiche specifiche di MQL, sarebbe più logico fare il contrario - impostare la priorità del passaggio del parametro non per valore (come ora), ma per riferimento const (i cui benefici sono particolarmente evidenti nell'esempio delle stringhe).

void f(       string  ) { Print( __FUNCSIG__ ); } //1
void f( const string& ) { Print( __FUNCSIG__ ); } //2
string g() { return "ABCDEF4"; }
void OnStart()
{
          string text1 = "ABCDEF1";
    const string text2 = "ABCDEF2";
//  вызываемая функция: сейчас  предлагается
    f( text1 );     //    1       2               
    f( text2 );     //    *       2 потому что const или оставить *
    f( "ABCDEF3" ); //    1       1
    f( g());        //    1       1
//Примечание: * - неопределенность
}

Non è chiaro perché passare (in realtà copiare) stringhe lunghe per valore quando può essere fatto per riferimento.

 

Errore di compilazione

#import  "Test.dll" //Error: '#import' - #import was not closed
#include "Test.h"
#import
//Test.h
void f();

Perché spostare manualmente il contenuto del file .h (specialmente perché può cambiare di volta in volta) quando puoi semplicemente includerlo?

 

Buon pomeriggio, potreste per favore consigliarmi?

Come scriverei risultati dell'ottimizzazione in un file usando la Local Network Farm o MQL5 Cloud Network?

C'è una procedura in OnTester(), usa:

string toWrite = "test";
fileHandle=FileOpen(fileName,FILE_CSV|FILE_READ|FILE_WRITE|FILE_ANSI|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON,",");
FileWrite(fileHandle,toWrite);
FileClose(fileHandle);

Quando si usano gli agenti locali, il file con i risultati dell'ottimizzazione viene creato nella cartella condivisa, quando si usa la Local Network Farm o MQL5 Cloud Network, non c'è nessun file.

Тестирование стратегий - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
Тестирование стратегий - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
  • www.metatrader5.com
Тестер стратегий позволяет тестировать и оптимизировать торговые стратегии (советники) перед началом использования их в реальной торговле. При тестировании советника происходит его однократная прогонка с начальными параметрами на исторических данных. При оптимизации торговая стратегия прогоняется несколько раз с различным набором параметров...
 
Nikolai Semko: COSA C'È DI SBAGLIATO? DA DOVE VIENE IL RALLENTAMENTO?

Un controllo ha rivelato che:

  1. Mappature SQRT in istruzioni dirette della CPU

  2. SQRT + i calcoli matematici vanno senza rami e un'istruzione (128 bit di dati) calcola due radici in una volta sola

    Questo codice si trasforma nel seguente codice assembler SSE:
             D1=sqrt((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y));
             D2=sqrt((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y));
             D3=sqrt((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y));
             D4=sqrt((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y));
             D5=sqrt((X5-X)*(X5-X)+(Y5-Y)*(Y5-Y));
             D6=sqrt((X6-X)*(X6-X)+(Y6-Y)*(Y6-Y));
             D7=sqrt((X7-X)*(X7-X)+(Y7-Y)*(Y7-Y));
             D8=sqrt((X8-X)*(X8-X)+(Y8-Y)*(Y8-Y));
            ...
            sqrtsd  xmm1, xmm1
            unpcklpd        xmm4, xmm4
            movapd  xmm3, xmmword ptr [rsp + 432]
            unpcklpd        xmm3, xmmword ptr [rsp + 384]
            subpd   xmm3, xmm4
            mulpd   xmm3, xmm3
            unpcklpd        xmm0, xmm0
            movapd  xmm5, xmmword ptr [rsp + 416]
            unpcklpd        xmm5, xmmword ptr [rsp + 400]
            subpd   xmm5, xmm0
            mulpd   xmm5, xmm5
            addpd   xmm5, xmm3
            sqrtpd  xmm8, xmm5
            movapd  xmm5, xmmword ptr [rsp + 464]
            subpd   xmm5, xmm4
            mulpd   xmm5, xmm5
            movapd  xmm7, xmm9
            subpd   xmm7, xmm0
            mulpd   xmm7, xmm7
            addpd   xmm7, xmm5
            movapd  xmm6, xmm10
            unpcklpd        xmm6, xmm11
            subpd   xmm6, xmm4
            movapd  xmm3, xmmword ptr [rsp + 368]
            unpcklpd        xmm3, xmmword ptr [rsp + 352]
            subpd   xmm3, xmm0
            movapd  xmm4, xmm8
            shufpd  xmm4, xmm4, 1
            sqrtpd  xmm5, xmm7
            mulpd   xmm6, xmm6
            mulpd   xmm3, xmm3
            addpd   xmm3, xmm6
            sqrtpd  xmm15, xmm3
            movapd  xmm0, xmm14
            unpcklpd        xmm0, xmmword ptr [rsp + 336]
            subpd   xmm0, xmm2
            mulpd   xmm0, xmm0
            movapd  xmm2, xmm0
            shufpd  xmm2, xmm2, 1
            addsd   xmm2, xmm0
            movapd  xmm0, xmm15
            shufpd  xmm0, xmm0, 1
            sqrtsd  xmm12, xmm2
    Questa è un'opera d'arte in realtà. 8 radici sono state calcolate in 4 chiamate di un'istruzione dell'assemblatore. Due numeri doppi sono valutati in una chiamata.

  3. Quando si opera attraverso un array, tutto va come al solito con controlli, ramificazioni e perdite sulla conversione dell'indice doppio -> intero.

  4. Quando si lavora con gli array in questo esempio c'è una costante mescolanza FPU/ALU che è molto negativa per la produttività

  5. L'ottimizzazione dell'accesso all'array dinamico è grande - oltre ogni lode. Ma mischiare operazioni FPU/ALU + doppio -> intero + ramificazione fa perdere tempo

La conclusione generale: la matematica in MQL5 vince grazie alla perfetta ottimizzazione. Qui non sono gli array a perdere, ma vince la matematica.

 

Ed ecco quale pornografia è stata fatta sullo stesso codice da Visual C++ 2017 x64 con ottimizzazioni complete:

; 52   :       int X=pos%Width;
; 53   :       int Y=int(pos/Width);
; 54   :       
; 55   :       D1=sqrt((X1-X)*(X1-X)+(Y1-Y)*(Y1-Y));

  0046 f 0 f 28 c8         movaps  xmm1, xmm0
  00472 8 b c3            mov     eax, ebx
  00474 99               cdq
  00475 45 0 f 57 db      xorps   xmm11, xmm11
  00479 f7 ff            idiv    edi
  0047 b 0 f 57 f6         xorps   xmm6, xmm6
  0047 e 41 0 f 28 c4      movaps  xmm0, xmm12
  00482 f2 44 0 f 2 a d8   cvtsi2sd xmm11, eax
  00487 f2 0 f 2 a f2      cvtsi2sd xmm6, edx
  0048 b f2 41 0 f 5 c cb   subsd   xmm1, xmm11
  00490 f2 0 f 5 c c6      subsd   xmm0, xmm6
  00494 f2 0 f 59 c9      mulsd   xmm1, xmm1
  00498 f2 0 f 59 c0      mulsd   xmm0, xmm0
  0049 c f2 0 f 58 c1      addsd   xmm0, xmm1
  004 a0 e8 00 00 00 00   call    sqrt

; 56   :       D2=sqrt((X2-X)*(X2-X)+(Y2-Y)*(Y2-Y));
; 57   :       D3=sqrt((X3-X)*(X3-X)+(Y3-Y)*(Y3-Y));

  004 a5 41 0 f 28 cf      movaps  xmm1, xmm15
  004 a9 41 0 f 28 c6      movaps  xmm0, xmm14
  004 ad f2 0 f 5 c c6      subsd   xmm0, xmm6
  004 b1 f2 41 0 f 5 c cb   subsd   xmm1, xmm11
  004 b6 f2 0 f 59 c0      mulsd   xmm0, xmm0
  004 ba f2 0 f 59 c9      mulsd   xmm1, xmm1
  004 be f2 0 f 58 c1      addsd   xmm0, xmm1
  004 c2 e8 00 00 00 00   call    sqrt

; 58   :       D4=sqrt((X4-X)*(X4-X)+(Y4-Y)*(Y4-Y));

  004 c7 f2 0 f 10 8 c 24
        90 01 00 00      movsd   xmm1, QWORD PTR Y4$1$[rsp]
  004 d0 f2 0 f 10 84 24
        98 01 00 00      movsd   xmm0, QWORD PTR X4$1$[rsp]
  004 d9 f2 41 0 f 5 c cb   subsd   xmm1, xmm11
  004 de f2 0 f 5 c c6      subsd   xmm0, xmm6
  004 e2 f2 0 f 59 c9      mulsd   xmm1, xmm1
  004 e6 f2 0 f 59 c0      mulsd   xmm0, xmm0
  004 ea f2 0 f 58 c1      addsd   xmm0, xmm1
  004 ee e8 00 00 00 00   call    sqrt

; 59   :       D5=sqrt((X5-X)*(X5-X)+(Y5-Y)*(Y5-Y));
; 60   :       D6=sqrt((X6-X)*(X6-X)+(Y6-Y)*(Y6-Y));
; 61   :       D7=sqrt((X7-X)*(X7-X)+(Y7-Y)*(Y7-Y));
; 62   :       D8=sqrt((X8-X)*(X8-X)+(Y8-Y)*(Y8-Y));

  004 f3 f2 0 f 10 44 24
        20               movsd   xmm0, QWORD PTR X8$1$[rsp]
  004 f9 41 0 f 28 c8      movaps  xmm1, xmm8
  004 fd f2 0 f 5 c c6      subsd   xmm0, xmm6
  00501 f2 41 0 f 5 c cb   subsd   xmm1, xmm11
  00506 f2 0 f 59 c0      mulsd   xmm0, xmm0
  0050 a f2 0 f 59 c9      mulsd   xmm1, xmm1
  0050 e f2 0 f 58 c1      addsd   xmm0, xmm1
  00512 e8 00 00 00 00   call    sqrt
  00517 f2 0 f 10 4 c 24
        28               movsd   xmm1, QWORD PTR Y2$1$[rsp]
  0051 d 41 0 f 28 c5      movaps  xmm0, xmm13
  00521 f2 44 0 f 10 44
        24 30            movsd   xmm8, QWORD PTR Y5$1$[rsp]
  00528 f2 41 0 f 5 c cb   subsd   xmm1, xmm11
  0052 d f2 44 0 f 10 54
        24 40            movsd   xmm10, QWORD PTR Y6$1$[rsp]
  00534 f2 0 f 5 c c6      subsd   xmm0, xmm6
  00538 f2 44 0 f 10 64
        24 50            movsd   xmm12, QWORD PTR Y7$1$[rsp]
  0053 f f2 45 0 f 5 c c3   subsd   xmm8, xmm11
  00544 f2 0 f 10 7 c 24
        38               movsd   xmm7, QWORD PTR X5$1$[rsp]
  0054 a f2 45 0 f 5 c d3   subsd   xmm10, xmm11
  0054 f f2 44 0 f 10 4 c
        24 48            movsd   xmm9, QWORD PTR X6$1$[rsp]
  00556 f2 45 0 f 5 c e3   subsd   xmm12, xmm11
  0055 b f2 44 0 f 10 5 c
        24 58            movsd   xmm11, QWORD PTR X7$1$[rsp]
  00562 f2 0 f 5 c fe      subsd   xmm7, xmm6
  00566 f2 0 f 59 c0      mulsd   xmm0, xmm0
  0056 a f2 44 0 f 5 c ce   subsd   xmm9, xmm6
  0056 f f2 0 f 59 c9      mulsd   xmm1, xmm1
  00573 f2 44 0 f 5 c de   subsd   xmm11, xmm6
  00578 f2 0 f 58 c1      addsd   xmm0, xmm1
  0057 c e8 00 00 00 00   call    sqrt
  00581 f2 0 f 59 ff      mulsd   xmm7, xmm7
  00585 f2 45 0 f 59 c0   mulsd   xmm8, xmm8
  0058 a f2 41 0 f 58 f8   addsd   xmm7, xmm8
  0058 f 0 f 28 c7         movaps  xmm0, xmm7
  00592 e8 00 00 00 00   call    sqrt
  00597 f2 45 0 f 59 c9   mulsd   xmm9, xmm9
  0059 c f2 45 0 f 59 d2   mulsd   xmm10, xmm10
  005 a1 f2 45 0 f 58 ca   addsd   xmm9, xmm10
  005 a6 41 0 f 28 c1      movaps  xmm0, xmm9
  005 aa e8 00 00 00 00   call    sqrt
  005 af f2 45 0 f 59 db   mulsd   xmm11, xmm11
  005 b4 f2 45 0 f 59 e4   mulsd   xmm12, xmm12
  005 b9 f2 45 0 f 58 dc   addsd   xmm11, xmm12
  005 be 41 0 f 28 c3      movaps  xmm0, xmm11
  005 c2 e8 00 00 00 00   call    sqrt
  005 c7 f2 0 f 10 84 24
        88 01 00 00      movsd   xmm0, QWORD PTR Y1$1$[rsp]

; 63   : 
; 64   :       double d=fabs(D1+D3+D4+D8)/(D1+D2+D3+D4+D5+D6+D7+D8);

Un multiplo non qualificato del codice generato in MQL5.

Sorprendentemente, MSVC non cerca nemmeno di ottimizzare - tutta la matematica è guidata attraverso le librerie come se fosse stata scritta per un processore di 20 anni fa. E abilitare il set di comandi AVX non cambia affatto il comportamento del compilatore.

File C++ di prova allegato. Non c'è nessun errore nell'esempio di test, quindi non esprimete il pensiero di "un errore nell'esempio di test".

File:
Test.cpp.zip  1 kb