Perguntas sobre OOP em MQL5 - página 70

 
Maxim Kuznetsov:

isto é chamado "loop unrolling" e é feito pelo compilador sem qualquer OO e modelos (pelo menos deveria ser).

Se você olhar para o código intermediário (assembler), há apenas operações N consecutivas em vez de um loop.

E você pode nos dizer o que acontece quando uma função é chamada recursivamente?

 
Dmitry Fedoseev:

Você pode me dizer o que acontece quando uma função é chamada recursivamente?

não há chamada recursiva para as funções alvo :-)

No exemplo acima dado N:=const, a recorrência ocorre apenas quando o código é gerado a partir de um modelo e este é adaptado. No link, uma reviravolta inteligente é fazer cair o ciclo constante em recursividade de modelo e chamá-lo de palavra inteligente

se as macros tivessem loops, seria escrito assim

#for x=0, x<N, x++

print("x=%d",x);

#endfor

e após o macro processador se desdobraria em uma seqüência de N príncipes. (o que realmente aconteceu, apenas através de classes de modelos)

Ou seja, o truque só funciona se N for conhecido em tempo de compilação

 
Maxim Kuznetsov:

e não há chamada recursiva para as funções alvo :-)

No exemplo dado no link N:=const, a recorrência é apenas na geração de código a partir de um modelo e aquele é a cauda. No link, uma reviravolta inteligente é fazer cair o ciclo constante em recursividade de modelo e chamá-lo de palavra inteligente

se as macros tivessem loops, seria escrito assim

#for x=0, x<N, x++

print("x=%d",x);

#endfor

e após o macro processador se desdobraria em uma seqüência de N príncipes. (o que realmente aconteceu, apenas através de classes de modelos)

Portanto, o truque só funciona se N for conhecido em tempo de compilação

Você não vai acreditar, mas eu sei como funcionam os modelos e o que N existe, e qual é o resultado. E minha pergunta sobre a chamada recursiva de função era exatamente sobre a chamada recursiva de função, não sobre como lá?

 
Dmitry Fedoseev:

Você não vai acreditar, mas eu sei como funcionam os modelos e o que é o N e qual é o resultado. E minha pergunta sobre a chamada recursiva de função era exatamente sobre a chamada recursiva de função, não sobre como lá?

é como um exame de "ousadia"? :-) Eu de alguma forma pensei que este exemplo estava sendo discutido... Eu estava errado :-)

Se o compilador puder converter a recorrência em uma cauda (ou se for explicitamente isso, ou se lhe foi dito), então fisicamente não haverá recorrência - ele fará um laço (switch back) e cada iteração "pisoteará" a estrutura da pilha anterior.

 
Maxim Kuznetsov:

isto é algum tipo de exame de "ousadia"? :-) Eu de alguma forma pensei que este exemplo estava sendo discutido...eu estava errado :-)

Se o compilador puder converter a recursividade em uma recursividade de cauda (ou se for explicitamente assim ou tiver sido dito para fazê-lo), então fisicamente não haverá recursividade - ele fará um laço (switch back) e cada iteração "pisoteará" a estrutura da pilha anterior.

O que isso tem a ver com fraqueza? Apenas uma pergunta. Bem, não, então não.

 
fxsaber:

Eu não quero nem me incomodar. Eu fiz estruturas simples.



Por que razão o acesso ao primeiro campo de uma estrutura simples depende de seu tamanho - não entendo.

Huh. É trivial - o número de bits a multiplicar é mais)))) Certifique-se de que o número de bits na representação binária do tamanho da estrutura era o mesmo)))) Estúpido processador, assim como um homem, mais tempo para multiplicar 1111*101 do que 1111*10)
 
Vladimir Simakov:
Huh. É trivial - o número de bits para multiplicação é mais)))) Certifique-se de que o número de bits na representação binária do tamanho da estrutura era o mesmo)))) Estúpido processador, assim como um homem, mais tempo para multiplicar 1111*101 do que 1111*10)

Eu não vou verificar, há muitas outras tarefas. Mas acho difícil de acreditar.

 

Em ME, eu trabalho com mqh, pressione ALT+N - a vista em árvore na janela do Navegador mostra a localização do arquivo.

Agora eu quero fazer seu inlude para abrir um arquivo mq5. Eu arrasto mqh da árvore para mq5, mas não é gerada nenhuma linha de inclusão apropriada.

 
fxsaber:

Eu não vou verificar, há muitas outras tarefas. Mas acho difícil de acreditar.

template <typename T>
size_t Func(T* arr,size_t arrSize)
{
000000013 FFC1DA0  mov         qword ptr [rsp+10 h],rdx  
000000013 FFC1DA5  mov         qword ptr [rsp+8],rcx  
000000013 FFC1DAA  push        rbp  
000000013 FFC1DAB  push        rdi  
000000013 FFC1DAC  sub         rsp,148 h  
000000013 FFC1DB3  lea         rbp,[rsp+20 h]  
000000013 FFC1DB8  mov         rdi,rsp  
000000013 FFC1DBB  mov         ecx,52 h  
000000013 FFC1DC0  mov         eax,0 CCCCCCCCh  
000000013 FFC1DC5  rep stos    dword ptr [rdi]  
000000013 FFC1DC7  mov         rcx,qword ptr [rsp+168 h]  
000000013 FFC1DCF  lea         rcx,[__116109BC_Test@cpp (013 FFD5029h)]  
000000013 FFC1DD6  call        __CheckForDebuggerJustMyCode (013 FFC10B9h)  
    // Write
    for (size_t i = 0; i <arrSize; ++i)
000000013 FFC1DDB  mov         qword ptr [rbp+8],0  
000000013 FFC1DE3  jmp         Func<STRUCT1>+50 h (013 FFC1DF0h)  
000000013 FFC1DE5  mov         rax,qword ptr [rbp+8]  
000000013 FFC1DE9  inc         rax  
000000013 FFC1DEC  mov         qword ptr [rbp+8],rax  
000000013 FFC1DF0  mov         rax,qword ptr [arrSize]  
000000013 FFC1DF7  cmp         qword ptr [rbp+8],rax  
000000013 FFC1DFB  jae         Func<STRUCT1>+71 h (013 FFC1E11h)  
        arr[i].i = i;
000000013 FFC1DFD  imul        rax,qword ptr [rbp+8],18 h  
000000013 FFC1E02  mov         rcx,qword ptr [arr]  
000000013 FFC1E09  mov         edx,dword ptr [rbp+8]  
000000013 FFC1E0C  mov         dword ptr [rcx+rax],edx  
000000013 FFC1E0F  jmp         Func<STRUCT1>+45 h (013 FFC1DE5h)  

    size_t Sum = 0;
000000013 FFC1E11  mov         qword ptr [Sum],0  

    // Read
    for (size_t i = 0; i < arrSize; ++i)
000000013 FFC1E19  mov         qword ptr [rbp+48 h],0  
000000013 FFC1E21  jmp         Func<STRUCT1>+8 Eh (013 FFC1E2Eh)  
000000013 FFC1E23  mov         rax,qword ptr [rbp+48 h]  
000000013 FFC1E27  inc         rax  
000000013 FFC1E2A  mov         qword ptr [rbp+48 h],rax  
000000013 FFC1E2E  mov         rax,qword ptr [arrSize]  
000000013 FFC1E35  cmp         qword ptr [rbp+48 h],rax  
000000013 FFC1E39  jae         Func<STRUCT1>+0 BBh (013 FFC1E5Bh)  
        Sum += arr[i].i;
000000013 FFC1E3B  imul        rax,qword ptr [rbp+48 h],18 h  
000000013 FFC1E40  mov         rcx,qword ptr [arr]  
000000013 FFC1E47  movsxd      rax,dword ptr [rcx+rax]  
000000013 FFC1E4B  mov         rcx,qword ptr [Sum]  
000000013 FFC1E4F  add         rcx,rax  
000000013 FFC1E52  mov         rax,rcx  
000000013 FFC1E55  mov         qword ptr [Sum],rax  
000000013 FFC1E59  jmp         Func<STRUCT1>+83 h (013 FFC1E23h)  

    return Sum + arrSize;
000000013 FFC1E5B  mov         rax,qword ptr [arrSize]  
000000013 FFC1E62  mov         rcx,qword ptr [Sum]  
000000013 FFC1E66  add         rcx,rax  
000000013 FFC1E69  mov         rax,rcx  
}
000000013 FFC1E6C  lea         rsp,[rbp+128 h]  

É para uma estrutura pequena.

template <typename T>
size_t Func(T* arr,size_t arrSize)
{
000000013 FFC1EB0  mov         qword ptr [rsp+10 h],rdx  
000000013 FFC1EB5  mov         qword ptr [rsp+8],rcx  
000000013 FFC1EBA  push        rbp  
000000013 FFC1EBB  push        rdi  
000000013 FFC1EBC  sub         rsp,148 h  
000000013 FFC1EC3  lea         rbp,[rsp+20 h]  
000000013 FFC1EC8  mov         rdi,rsp  
000000013 FFC1ECB  mov         ecx,52 h  
000000013 FFC1ED0  mov         eax,0 CCCCCCCCh  
000000013 FFC1ED5  rep stos    dword ptr [rdi]  
000000013 FFC1ED7  mov         rcx,qword ptr [rsp+168 h]  
000000013 FFC1EDF  lea         rcx,[__116109BC_Test@cpp (013 FFD5029h)]  
000000013 FFC1EE6  call        __CheckForDebuggerJustMyCode (013 FFC10B9h)  
    // Write
    for (size_t i = 0; i <arrSize; ++i)
000000013 FFC1EEB  mov         qword ptr [rbp+8],0  
000000013 FFC1EF3  jmp         Func<STRUCT3>+50 h (013 FFC1F00h)  
000000013 FFC1EF5  mov         rax,qword ptr [rbp+8]  
000000013 FFC1EF9  inc         rax  
000000013 FFC1EFC  mov         qword ptr [rbp+8],rax  
000000013 FFC1F00  mov         rax,qword ptr [arrSize]  
000000013 FFC1F07  cmp         qword ptr [rbp+8],rax  
000000013 FFC1F0B  jae         Func<STRUCT3>+71 h (013 FFC1F21h)  
        arr[i].i = i;
000000013 FFC1F0D  imul        rax,qword ptr [rbp+8],58 h  
000000013 FFC1F12  mov         rcx,qword ptr [arr]  
000000013 FFC1F19  mov         edx,dword ptr [rbp+8]  
000000013 FFC1F1C  mov         dword ptr [rcx+rax],edx  
000000013 FFC1F1F  jmp         Func<STRUCT3>+45 h (013 FFC1EF5h)  

    size_t Sum = 0;
000000013 FFC1F21  mov         qword ptr [Sum],0  

    // Read
    for (size_t i = 0; i < arrSize; ++i)
000000013 FFC1F29  mov         qword ptr [rbp+48 h],0  
000000013 FFC1F31  jmp         Func<STRUCT3>+8 Eh (013 FFC1F3Eh)  
000000013 FFC1F33  mov         rax,qword ptr [rbp+48 h]  
000000013 FFC1F37  inc         rax  
000000013 FFC1F3A  mov         qword ptr [rbp+48 h],rax  
000000013 FFC1F3E  mov         rax,qword ptr [arrSize]  
000000013 FFC1F45  cmp         qword ptr [rbp+48 h],rax  
000000013 FFC1F49  jae         Func<STRUCT3>+0 BBh (013 FFC1F6Bh)  
        Sum += arr[i].i;
000000013 FFC1F4B  imul        rax,qword ptr [rbp+48 h],58 h  
000000013 FFC1F50  mov         rcx,qword ptr [arr]  
000000013 FFC1F57  movsxd      rax,dword ptr [rcx+rax]  
000000013 FFC1F5B  mov         rcx,qword ptr [Sum]  
000000013 FFC1F5F  add         rcx,rax  
000000013 FFC1F62  mov         rax,rcx  
000000013 FFC1F65  mov         qword ptr [Sum],rax  
000000013 FFC1F69  jmp         Func<STRUCT3>+83 h (013 FFC1F33h)  

    return Sum + arrSize;
000000013 FFC1F6B  mov         rax,qword ptr [arrSize]  
000000013 FFC1F72  mov         rcx,qword ptr [Sum]  
000000013 FFC1F76  add         rcx,rax  
000000013 FFC1F79  mov         rax,rcx  
}
000000013 FFC1F7C  lea         rsp,[rbp+128 h]  

Isto é para um grande.

VS2019, Debug x64, em seu lançamento, os alinhou, mas a velocidade é a mesma.

A única diferença está nas instruções imul, o terceiro operando, em dois lugares. A instrução é apenas que, calculando o offset na matriz, e o terceiro operando éo tamanho da estrutura em bytes.

Portanto, sem misticismo - leis da física em ação.

 
Vladimir Simakov:

Portanto, sem misticismo - as leis da física estão em ação.

se você escrever tais aulas:

//+------------------------------------------------------------------+
struct STRUCT
{
   int i;
   double d;
   uchar uc[16];
};
//+------------------------------------------------------------------+
class A
{
private:
   int i;
   double d;
   uchar uc[16];
public:
   A(const STRUCT &ini) { i = ini.i; d = ini.d; ArrayCopy(uc,ini.uc); }
};
//+------------------------------------------------------------------+
class B
{
private:
   STRUCT data;
public:
   B(const STRUCT &ini) { data = ini; }
};
//+------------------------------------------------------------------+

A julgar por sua pesquisa, a classe B será mais lenta de executar se você usar campos de estrutura frequentemente nos cálculos?

Razão: