错误、漏洞、问题 - 页 2164

 
Vladimir Pastushak:

产品描述 中的空间非常小。

3600个字符对于大型和严肃的节目来说是非常短的。

我想很多人都会同意我的看法。

你需要不少于5000-10000个字符来描述程序。或者至少有一个带有程序设置名称的标签

主持人可以随时要求清除水。

现在我正在写方案描述,光是描述设置就用了3600个字符,但我连一半的功能都没有描述......

弗拉基米尔,你买过东西吗?你花了多少时间阅读手册?

没有人会去读一本多卷的书,他们甚至不会看超过3-5分钟的视频。
解决办法只有一个:在程序界面上设置工具提示,其他地方几乎都是如此。类似于互动教程的东西。而针对高级用户的详细说明可以放在博客或其网站上。谁想要它,谁就会找到它并下载它。

 
Vladimir Pastushak:

产品描述 中的空间非常小。

3600个字符对于大型和严肃的节目来说是非常短的。

我想很多人都会同意我的看法。

你需要不少于5000-10000个字符来描述程序。或者至少有一个带有程序设置名称的标签

主持人可以随时要求清除水。

现在我正在写程序描述,光是描述设置就用了3600个字符,连一半的功能都没有......

我不同意。简洁是人才的姐妹。

"不要以为在你的许多话中,你会被听到"。

马太福音》6:7。

 
Andrey Khatimlianskii:

弗拉基米尔,你买过东西吗?你花了多少时间阅读说明?

没有人会读一本多卷的书,他们甚至不会看一个3到5分钟的视频。
只有一个办法--在程序的界面上添加提示,现在几乎所有的地方都这么做。类似于互动教程的东西。而针对高级用户的详细说明可以放在博客或其网站上。谁想要它,谁就会找到它并下载它。

那些不看不买的人,你是否在不了解产品用途的情况下买了很多产品?

那么我们是否应该在博客上公布一切?

 
Nikolai Semko:

我不同意。简洁是人才的姐妹。

"不要以为在你的言语中你会被听到"。

马太福音》6:7。

我同意,但即使是简短的3600也是不够的......。

 
Vladimir Pastushak:

那些不看不买的人,你是否在不了解产品用途的情况下买了很多产品?

那么我们是否应该在博客上公布一切?

从手册中了解到产品的用途?

这很傻。我将下载并感受一下演示。

 
A100:

这段代码是基于一个编译器的缺陷

结果:1...为什么不是2?

而C++在编译时报告了一个错误,因为这两个函数显然都适合,此外,语法不允许明确地调用函数(2)

此外,考虑到MQL的具体特点,更合理的做法是反其道而行之--不通过值(如现在),而是通过常量引用来设置传递参数的优先级(其好处在字符串的例子中尤为明显)。

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
//Примечание: * - неопределенность
}

不清楚为什么要通过值来传递(实际上是复制)长字符串,因为它可以通过引用来完成。

 

编译错误

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

为什么要手动移动.h文件的内容(特别是因为它可能不时地发生变化),而你可以直接包含它?

 

下午好,能否请您提供建议。

如何使用本地网络农场或MQL5云网络将优化结果 写入文件中?

在OnTester()中有一个程序,使用。

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);

当使用本地代理时,优化结果的文件会在共享文件夹中创建,当使用本地网络农场或MQL5云网络时,没有文件。

Тестирование стратегий - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
Тестирование стратегий - Алгоритмический трейдинг, торговые роботы - MetaTrader 5
  • www.metatrader5.com
Тестер стратегий позволяет тестировать и оптимизировать торговые стратегии (советники) перед началом использования их в реальной торговле. При тестировании советника происходит его однократная прогонка с начальными параметрами на исторических данных. При оптимизации торговая стратегия прогоняется несколько раз с различным набором параметров...
 
Nikolai Semko: 什么是错的?增长放缓从何而来?

经检查发现。

  1. SQRT被直接映射为CPU指令

  2. SQRT+数学计算 没有分支,一条指令(128位数据)就能同时计算两个根。

    这段代码变成了以下汇编的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
    这实际上是一件艺术作品。一个汇编指令的4次调用就能计算出8个根。两个双数在一次调用中被评估。

  3. 当通过一个数组进行操作时,一切都像往常一样,在转换双数->整数索引时进行检查、分支和损失。

  4. 在这个例子中处理数组时,不断有FPU/ALU混合,这对生产力非常不利。

  5. 对动态数组访问的优化非常好--无可非议。但混合FPU/ALU操作+双数->整数+分支的方式会浪费时间

总的结论是:MQL5中的数学由于完美的优化而获胜。这里输的不是数组,而是数学赢了。

 

而这里是用Visual C++ 2017 x64在相同的代码上做了哪些色情的东西,并进行了充分的优化。

; 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);

在MQL5中生成的代码的一个不合格的倍数。

令人惊讶的是,MSVC甚至没有尝试进行优化--所有的数学运算都是通过库来驱动的,就好像它是为20年前的处理器编写的。而启用AVX命令集根本不会改变编译器的行为。

附上测试C++文件。测试例子中没有错误,所以不要表达 "测试例子中有错误 "的想法。

附加的文件:
Test.cpp.zip  1 kb