错误、漏洞、问题 - 页 2500 1...249324942495249624972498249925002501250225032504250525062507...3184 新评论 Igor Makanu 2019.07.07 13:20 #24991 Vict: 你在一个错误的地方挖掘。 你根本不需要对齐,处理器需要它,而不是为了在两条高速缓存线上得到一些int。 没有,处理器缓存根本没有加载数据预取,不同的缓存级别根本没有加载过渡预测,pack()根本无法到达那里(进入缓存),任何算术操作(2个int的加法)而不是在1或3个(假设的)时钟周期上执行,都会导致数据排列分析,等等。 在物理层面上,它应该是这样工作的:编译器在其中创建了可执行代码,是的,会有pack(),但是当从RAM加载数据时,它将只读取int数据,数据段指针将立即被移到pack()字节(而不是int字节)。 虽然我可能是错的,但现在所有的进程(包括处理器本身)都被虚拟化和优化了--这是我的推理,因为我在学习时读了关于Pentium-1的书--....。当年太贵了 )))) [删除] 2019.07.07 13:28 #24992 Igor Makanu: 没有,处理器缓存根本没有加载数据预取,不同的缓存级别根本没有加载过渡预测,pack()根本无法到达那里(进入缓存),任何算术操作(2个int的加法)而不是在1或3个(假设的)时钟周期上执行,都会导致数据排列分析,等等。 在物理层面上,它应该是这样工作的:编译器在其中创建了可执行代码,是的,会有pack(),但是当从RAM中加载数据时,只会读取int数据,数据段指针会立即移动到pack()字节(而不是int字节)。 我并没有说pack()是CPU的服务信息,我的意思是所有这些与CPU而不是与程序员的利益相一致的舞蹈。当然,它是由编译器通过在结构中插入一个空白来实现的。 fxsaber 2019.07.07 13:35 #24993 Alexey Viktorov: 也就是说,在MQL5中根本就没有对齐。 它已经存在很长时间了。 [删除] 2019.07.07 13:35 #24994 Vict: 你在错误的地方挖掘,对齐根本不适合你。 好吧,虽然我可以想到的一个真正的用途是在多线程环境中,安排数据,使不同的核心不写到同一个缓存行,但由于不断的缓存同步,这确实会减慢性能。嗯,那里也有很多细微的差别,比如CPU类型。 Alexey Viktorov 2019.07.07 13:47 #24995 fxsaber: 它已经存在很长时间了。 你还记得是在哪里写的吗? Igor Makanu 2019.07.07 13:55 #24996 fxsaber: 那么我恐怕就失去了对准的意义 在字节中尝试了一下,看看对齐的效果如何。 #property strict const uint FFFF=0xFFFFFFFF; //+------------------------------------------------------------------+ struct A pack(4) { ushort j; }; //+------------------------------------------------------------------+ struct B pack(8) { ushort j; }; //+------------------------------------------------------------------+ union UnionCheckByte { uint byte_2x4[2]; A a; B b; }; //+------------------------------------------------------------------+ void OnStart() { UnionCheckByte tst; tst.byte_2x4[0]=FFFF; tst.byte_2x4[1]=FFFF; // заполним память 0xFFFFFFFF FFFFFFFF Print("0xFFFFFFFF FFFFFFFF = ",tst.byte_2x4[0],",",tst.byte_2x4[1]); // проверим tst.byte_2x4[0]=FFFF; tst.byte_2x4[1]=FFFF; // заполним память 0xFFFFFFFF FFFFFFFF tst.a.j=0; Print("A. = ",tst.byte_2x4[0],",",tst.byte_2x4[1]); // проверим tst.byte_2x4[0]=FFFF; tst.byte_2x4[1]=FFFF; // заполним память 0xFFFFFFFF FFFFFFFF tst.b.j=0; Print("B. = ",tst.byte_2x4[0],",",tst.byte_2x4[1]); // проверим } //+------------------------------------------------------------------+ 2019.07.07 17:51:30.601 tst (EURUSD,H1) 0xFFFFFFFFFF FFFFFFFFFF = 4294967295,4294967295 2019.07.07 17:51:30.601 tst (EURUSD,H1) A. = 4294901760,4294967295 2019.07.07 17:51:30.601 tst (EURUSD,H1) B. = 4294901760,4294967295 要么是我还没睡醒,要么是pack(4)/pack(8)对齐方式不起作用,我明确向编译器指定了结构 A和B的尺寸 即便如此。 ZeroMemory(tst.a); //tst.a.j=0; 没有变化 fxsaber 2019.07.07 14:01 #24997 Alexey Viktorov: 你还记得它是在哪里写的吗? 我不记得文档中是否有这个内容。 fxsaber 2019.07.07 14:03 #24998 Igor Makanu: 试图看看在字节中的对齐情况。 要么是我还没睡醒,要么是pack(4)/pack(8)对齐方式不起作用,我毫不含糊地告诉编译器结构 A和B的大小 这个讨论 就是这样开始的。事实证明,情况并非如此。 嗯,这个样本毕竟是不正确的。在清零ushort-field时,额外的字节根本不需要改变。 ZeroMemory很可能是由sizeof引导的,而它在这两种情况下都是2,是出于自身的某种原因。 Igor Makanu 2019.07.07 14:18 #24999 fxsaber: 所以这就是这次讨论的开始。 事实证明,根本就不是这样的。 1.那么,这个例子毕竟是不正确的。通过将ushort-field归零,额外的字节根本不需要改变。 2.ZeroMemory必须由sizeof引导,而在这两种情况下,由于某种原因,它是双倍的。 1.是的,我同意 2.ZeroMemory应该只是为我调零内存 我不认为在纯粹的MQL中使用pack()有任何意义,你最多可以使用.dll来处理数据,但它应该是有效的,这是开发人员说的。 fxsaber 2019.07.07 14:25 #25000 Igor Makanu: 2.ZeroMemory正是我所需要的,以重置内存。 它确实如此。 struct A pack(4) { short j; char i; }; union U { A a; uchar Bytes[sizeof(A)]; U() { ArrayInitialize(this.Bytes, (char)0xFF); } }; void OnStart() { U u; ArrayPrint(u.Bytes); // 255 255 255 255 ZeroMemory(u.a); ArrayPrint(u.Bytes); // 0 0 0 0 } 1...249324942495249624972498249925002501250225032504250525062507...3184 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
你在一个错误的地方挖掘。 你根本不需要对齐,处理器需要它,而不是为了在两条高速缓存线上得到一些int。
没有,处理器缓存根本没有加载数据预取,不同的缓存级别根本没有加载过渡预测,pack()根本无法到达那里(进入缓存),任何算术操作(2个int的加法)而不是在1或3个(假设的)时钟周期上执行,都会导致数据排列分析,等等。
在物理层面上,它应该是这样工作的:编译器在其中创建了可执行代码,是的,会有pack(),但是当从RAM加载数据时,它将只读取int数据,数据段指针将立即被移到pack()字节(而不是int字节)。
虽然我可能是错的,但现在所有的进程(包括处理器本身)都被虚拟化和优化了--这是我的推理,因为我在学习时读了关于Pentium-1的书--....。当年太贵了 ))))
没有,处理器缓存根本没有加载数据预取,不同的缓存级别根本没有加载过渡预测,pack()根本无法到达那里(进入缓存),任何算术操作(2个int的加法)而不是在1或3个(假设的)时钟周期上执行,都会导致数据排列分析,等等。
在物理层面上,它应该是这样工作的:编译器在其中创建了可执行代码,是的,会有pack(),但是当从RAM中加载数据时,只会读取int数据,数据段指针会立即移动到pack()字节(而不是int字节)。
我并没有说pack()是CPU的服务信息,我的意思是所有这些与CPU而不是与程序员的利益相一致的舞蹈。当然,它是由编译器通过在结构中插入一个空白来实现的。
也就是说,在MQL5中根本就没有对齐。
它已经存在很长时间了。
你在错误的地方挖掘,对齐根本不适合你。
好吧,虽然我可以想到的一个真正的用途是在多线程环境中,安排数据,使不同的核心不写到同一个缓存行,但由于不断的缓存同步,这确实会减慢性能。嗯,那里也有很多细微的差别,比如CPU类型。
它已经存在很长时间了。
你还记得是在哪里写的吗?
那么我恐怕就失去了对准的意义
在字节中尝试了一下,看看对齐的效果如何。
2019.07.07 17:51:30.601 tst (EURUSD,H1) 0xFFFFFFFFFF FFFFFFFFFF = 4294967295,4294967295
2019.07.07 17:51:30.601 tst (EURUSD,H1) A. = 4294901760,4294967295
2019.07.07 17:51:30.601 tst (EURUSD,H1) B. = 4294901760,4294967295
要么是我还没睡醒,要么是pack(4)/pack(8)对齐方式不起作用,我明确向编译器指定了结构 A和B的尺寸
即便如此。
没有变化你还记得它是在哪里写的吗?
我不记得文档中是否有这个内容。
试图看看在字节中的对齐情况。
要么是我还没睡醒,要么是pack(4)/pack(8)对齐方式不起作用,我毫不含糊地告诉编译器结构 A和B的大小
这个讨论 就是这样开始的。事实证明,情况并非如此。
嗯,这个样本毕竟是不正确的。在清零ushort-field时,额外的字节根本不需要改变。
ZeroMemory很可能是由sizeof引导的,而它在这两种情况下都是2,是出于自身的某种原因。
所以这就是这次讨论的开始。 事实证明,根本就不是这样的。
1.那么,这个例子毕竟是不正确的。通过将ushort-field归零,额外的字节根本不需要改变。
2.ZeroMemory必须由sizeof引导,而在这两种情况下,由于某种原因,它是双倍的。
1.是的,我同意
2.ZeroMemory应该只是为我调零内存
我不认为在纯粹的MQL中使用pack()有任何意义,你最多可以使用.dll来处理数据,但它应该是有效的,这是开发人员说的。
2.ZeroMemory正是我所需要的,以重置内存。
它确实如此。