错误、漏洞、问题 - 页 2505 1...249824992500250125022503250425052506250725082509251025112512...3184 新评论 Taras Slobodyanik 2019.07.09 10:21 #25041 编辑器中的一个长期存在的错误。 - 将文件保存在一个新的名称下(例如:name_v1.2)。- 将光标放在某个变量上(或函数调用)。- 按alt+g - 一个旧文件被打开,编辑跳转到它( Francuz 2019.07.09 11:45 #25042 Vict: 一般来说,我甚至没有想到。 这段代码有点过于复杂--我试着去找不适合缓存线的元素并直接敲击它,但是失败了(如果我想的话可能会成功,但是我觉得很无聊),而且我没有对代码做太大的改动。但这种方式更令人印象深刻--16次折叠中只有一次是针对不适合缓存行的元素进行的,但它的效果却很明显。 SZY:更客观地说,在这种情况下,通过插入两个短,而不是通过删除一个短来做RIGHT_ALIGNED(所以我们在两种情况下都会实现缓存行的两次更新)。速度的提升会比较小,但仍然是1.5倍左右。 对不起,但对准的用途在哪里?这不是这个例子的内容。 П.С.在没有评论的情况下,以粗糙的形式发布你的代码是对你的朋友的不尊重。 Ilyas 2019.07.09 12:32 #25043 正确地指出,增加了对齐方式,以便在第三方库中使用MQL结构对象,特别是dotnet。 当dotnet库被添加到支持dotnet时,对齐被添加到包结构/类的字段中。 简而言之,它的工作原理是这样的。 对于每一种类型(char、short、int...)都有一个默认的对齐方式(分别为1、2、4字节)。 对于结构领域,将选择两种排列的最小值:默认排列和用户定义的排列(通过打包)。 同时,打包对象的大小是以这样的方式设置的,即数组中对象字段的寻址总是 "正确的"(默认的一个字节是与打包一起设置的)。 正是因为后者,人们产生了错误的印象,认为数据包对齐了结构的大小;事实并非如此,字段地址是对齐的,这就需要对齐结构的大小。 比如说 struct A pack(8) { double d; char c; }; void OnStart() { Print(sizeof(A)); } 结果16,因此,对第一个字段d的寻址总是以8个字节对齐。 [删除] 2019.07.09 13:09 #25044 fxsaber: 我自己的运行情况没有显示出任何明显的差异。 我改进了原来的想法(在第一个代码中,地址被错误地计算了)。如果你不介意的话,看看你的结果会很有趣。 #define WRONG_ALIGNED #define CACHE_LINE_SIZE 64 struct Data { #ifdef WRONG_ALIGNED ushort pad; #else uint pad; #endif uint ar[CACHE_LINE_SIZE/sizeof(int)+1]; }; #import "msvcrt.dll" long memcpy(uint &, uint &, long); #import #define getaddr(x) memcpy(x, x, 0) void OnStart() { Data data[32768]; ZeroMemory(data); srand(GetTickCount()); ulong start_time = GetMicrosecondCount(); for(unsigned i = 0; i < 10000; ++ i) { int rndnum = rand(); while (++rndnum < 32768) { int index = int(CACHE_LINE_SIZE - getaddr(data[rndnum].ar[0]) % CACHE_LINE_SIZE) / sizeof(int); ++ data[rndnum].ar[index]; ++ data[rndnum].pad; } } Alert(GetMicrosecondCount() - start_time); Print(data[100].ar[0]); Print(data[100].pad); } /* WRONG_ALIGNED: 6206397 6185472 RIGHT_ALIGNED 4089827 4003213 */ 本质上,在有/无WRONG_ALIGNED的情况下都会发生同样的事情--在每一次我们向两个相邻的缓存行写东西的时候(向pad写东西总是写到正确的地址),唯一不同的是,在有WRONG_ALIGNED的情况下(不一定),ar中的一个条目发生在uint中,它不会完全进入缓存行,我有一个大约1.5倍的稳定差异。 Francuz 2019.07.09 13:38 #25045 Vict: 我已经解决了原来的想法(第一个代码没有正确计算地址)。如果你不介意的话,看看你的案例的结果会很有趣。 基本上在有/无WRONG_ALIGNED的情况下都会发生同样的事情--在每一次我们写到两个相邻的缓存行(pad条目总是正确的地址),唯一不同的是,在有WRONG_ALIGNED的情况下(不总是),ar中的一个条目发生在uint中,这不会影响整个缓存行,我有一个大约1.5倍的稳定差别。 请解释一下,你想通过这句话得到什么?在前面的例子中,它是垃圾代码。 int index = int(CACHE_LINE_SIZE - getaddr(data[rndnum].ar[0]) % CACHE_LINE_SIZE) / sizeof(int); [删除] 2019.07.09 13:43 #25046 Francuz: 请解释你想通过这句话得到什么?在前面的例子中,它是垃圾代码。 找到我们在当前缓存线中的位置(PAD所在的位置),并为ar[]取这样的索引,与之对应的元素在下一个缓存线中(也许元素在两个缓存线中都有WRONG_ALIGNED)。 Francuz 2019.07.09 14:05 #25047 Vict: 找到我们在当前缓存线中的位置(即pad所在的位置),并为ar[]取一个索引,使与之相关的元素在下一个缓存线中(也许该元素在WRONG_ALIGNED的两个缓存线中)。 现在我们谈论的是偏移。但你所展示的纯粹是一个合成的例子,在现实生活中永远不会发生。而在真实的例子中,速度的提升最多只有1%左右。你不应该为了这样一个微不足道的加速而大惊小怪。 П.С.另外,你对寄存器大小的计算也是错误的。 [删除] 2019.07.09 14:21 #25048 Francuz: 现在我们正在讨论流离失所问题。但你所展示的是一个纯粹的合成例子,在现实生活中永远不会遇到。在现实世界的例子中,速度的提高最多只有1%左右。你不应该对这样一个微不足道的加速度大惊小怪。 不,这是很真实的例子。只有25%的写入发生在缓存线接口处的 "问题 "地方。那是多少钱?例如,如果你有一个长的双数数组,一个缓存行只能容纳4个值,如果你不去管对齐问题(编译器也不帮你做),那么你就会有25%的问题双数位置--就像我的例子中那样。还有很多细微的差别,可以说是对准的,但我不会去说--我对这个问题不是很精通。 嗯,房子的主人。 P.S. 另外,你把寄存器的大小计算错了。 我其实根本没把他算进去 )) Francuz 2019.07.09 14:23 #25049 Vict: 不,这是一个完全现实的例子。其中,只有25%的条目出现在缓存行交界处的 "问题 "地方。是很多吗?例如,如果你有一个长的双数数组,一个缓存行只容纳4个值,如果你不关心对齐问题(编译器也不为你做),那么你会得到25%的问题双数--就像我的例子一样。还有很多细微的差别,这些差别说明了对齐的问题,但我不会谈论它们--我对这个问题的了解还不够。 好吧,你是老板。 我再一次说,你被寄存器的大小所迷惑。 [删除] 2019.07.09 14:24 #25050 Francuz: 你又一次混淆了寄存器的大小。 说明理由 1...249824992500250125022503250425052506250725082509251025112512...3184 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
编辑器中的一个长期存在的错误。
- 将文件保存在一个新的名称下(例如:name_v1.2)。
- 将光标放在某个变量上(或函数调用)。
- 按alt+g
- 一个旧文件被打开,编辑跳转到它(
一般来说,我甚至没有想到。
这段代码有点过于复杂--我试着去找不适合缓存线的元素并直接敲击它,但是失败了(如果我想的话可能会成功,但是我觉得很无聊),而且我没有对代码做太大的改动。但这种方式更令人印象深刻--16次折叠中只有一次是针对不适合缓存行的元素进行的,但它的效果却很明显。
SZY:更客观地说,在这种情况下,通过插入两个短,而不是通过删除一个短来做RIGHT_ALIGNED(所以我们在两种情况下都会实现缓存行的两次更新)。速度的提升会比较小,但仍然是1.5倍左右。
对不起,但对准的用途在哪里?这不是这个例子的内容。
П.С.在没有评论的情况下,以粗糙的形式发布你的代码是对你的朋友的不尊重。
正确地指出,增加了对齐方式,以便在第三方库中使用MQL结构对象,特别是dotnet。
当dotnet库被添加到支持dotnet时,对齐被添加到包结构/类的字段中。
简而言之,它的工作原理是这样的。
对于每一种类型(char、short、int...)都有一个默认的对齐方式(分别为1、2、4字节)。
对于结构领域,将选择两种排列的最小值:默认排列和用户定义的排列(通过打包)。
同时,打包对象的大小是以这样的方式设置的,即数组中对象字段的寻址总是 "正确的"(默认的一个字节是与打包一起设置的)。
正是因为后者,人们产生了错误的印象,认为数据包对齐了结构的大小;事实并非如此,字段地址是对齐的,这就需要对齐结构的大小。
比如说
结果16,因此,对第一个字段d的寻址总是以8个字节对齐。
我自己的运行情况没有显示出任何明显的差异。
我改进了原来的想法(在第一个代码中,地址被错误地计算了)。如果你不介意的话,看看你的结果会很有趣。
本质上,在有/无WRONG_ALIGNED的情况下都会发生同样的事情--在每一次我们向两个相邻的缓存行写东西的时候(向pad写东西总是写到正确的地址),唯一不同的是,在有WRONG_ALIGNED的情况下(不一定),ar中的一个条目发生在uint中,它不会完全进入缓存行,我有一个大约1.5倍的稳定差异。我已经解决了原来的想法(第一个代码没有正确计算地址)。如果你不介意的话,看看你的案例的结果会很有趣。
基本上在有/无WRONG_ALIGNED的情况下都会发生同样的事情--在每一次我们写到两个相邻的缓存行(pad条目总是正确的地址),唯一不同的是,在有WRONG_ALIGNED的情况下(不总是),ar中的一个条目发生在uint中,这不会影响整个缓存行,我有一个大约1.5倍的稳定差别。请解释一下,你想通过这句话得到什么?在前面的例子中,它是垃圾代码。
请解释你想通过这句话得到什么?在前面的例子中,它是垃圾代码。
找到我们在当前缓存线中的位置(PAD所在的位置),并为ar[]取这样的索引,与之对应的元素在下一个缓存线中(也许元素在两个缓存线中都有WRONG_ALIGNED)。
找到我们在当前缓存线中的位置(即pad所在的位置),并为ar[]取一个索引,使与之相关的元素在下一个缓存线中(也许该元素在WRONG_ALIGNED的两个缓存线中)。
现在我们谈论的是偏移。但你所展示的纯粹是一个合成的例子,在现实生活中永远不会发生。而在真实的例子中,速度的提升最多只有1%左右。你不应该为了这样一个微不足道的加速而大惊小怪。
П.С.另外,你对寄存器大小的计算也是错误的。现在我们正在讨论流离失所问题。但你所展示的是一个纯粹的合成例子,在现实生活中永远不会遇到。在现实世界的例子中,速度的提高最多只有1%左右。你不应该对这样一个微不足道的加速度大惊小怪。
不,这是很真实的例子。只有25%的写入发生在缓存线接口处的 "问题 "地方。那是多少钱?例如,如果你有一个长的双数数组,一个缓存行只能容纳4个值,如果你不去管对齐问题(编译器也不帮你做),那么你就会有25%的问题双数位置--就像我的例子中那样。还有很多细微的差别,可以说是对准的,但我不会去说--我对这个问题不是很精通。
嗯,房子的主人。
不,这是一个完全现实的例子。其中,只有25%的条目出现在缓存行交界处的 "问题 "地方。是很多吗?例如,如果你有一个长的双数数组,一个缓存行只容纳4个值,如果你不关心对齐问题(编译器也不为你做),那么你会得到25%的问题双数--就像我的例子一样。还有很多细微的差别,这些差别说明了对齐的问题,但我不会谈论它们--我对这个问题的了解还不够。
好吧,你是老板。
我再一次说,你被寄存器的大小所迷惑。
你又一次混淆了寄存器的大小。