需要帮助!无法解决这个问题,我遇到了硬件限制 - 页 15

 

终于搞清楚需要什么了,希望这个版本是最终版本。

如前所述,一切都很简单,就是拆分和平行,主要步骤。

1.a. 知道每个序列的开头和结尾在哪里是非常有用的(因为这个原因,我上次建议把它们的大小写在一个单独的文件中)。

б.你可以自己解析它们,但在这种情况下,你必须在从磁盘上读取文件的下一部分时回来,以读取先前的修剪序列。

接下来,我将考虑变体1.a。可能,它不是最佳的,但我更喜欢它。

2.知道了序列的大小和部分文件的内存大小(500 mb),我们可以计算出我们需要下载的部分文件的大小。

3.同时,我们计算序列的系数,因为我们知道每个序列的开始和结束。

4.每个序列的开始和结束都可以存储在多线程队列中(在计算步骤2时填充)。

5.计算结果--结构(数组来自结构,其中时间和系数+序列号))。

6.当分配的内存 初始大小(250 mb)的一半被处理后,重写过程开始,形成第二个队列,有开头和结尾

7.到了第一行的尽头,我们从第二行开始读;到了第二行的尽头,我们从第一行开始读。

8.你可以同时计算系数并从文件中读取。

9.但每一个系数的计算结果都应被储存起来,最好是在响应中一次性合并它们。

我们必须编写合并函数:将两个系数序列合并为一个子结果,将两个子结果合并为一个稍完整的子结果

10.合并过程也可以并行进行。

11.什么时候有结果?当从附加文件中读取的序列大小完成后,那么两个堆栈将成为空的,然后系数的计算将完成。

然后我们必须等待子结果进程的合并完成(也可以通过线程安全队列完成)。

并最终合并不同线程的子结果--结果。


这是一个具有所有可能的最大负荷的变体,也许有更好的东西--我会很高兴。

我需要功能。

从一个输入序列形成一个系数序列

将两个系数序列合并为一个子结果(这里可能会有精度损失)

将两个子结果合并为一个稍微完整的子结果(可能会有准确性的损失)

 
komposter:

我认为有可能发明一种巧妙的部分装载机制,但必须要有发明。

例如,在第一次读取时,为每一个通道找到在开始日期之前关闭的最后一笔交易,回过头来读取之前的X笔交易,记住文件中该交易结束的点。

之后,在结果中找到第一笔交易,然后只用新鲜的数据工作:从所需的点到新的实际日期读取文件,每次在数组中转移交易(得到固定大小的数组--X元素)。

这将解决多读(我们就是不需要)和内存(只有当我们能放置X百万个事务时)的问题。

是的,这就是算法会做的事。

  1. 调整所有交易数组的大小至X元素。
  2. Set SeekDate = StartDate.
  3. 打开文件,开始阅读,按顺序填充第一遍的交易数组。
  4. 如果对应于该通道的交易已经结束(没有足够的X交易),设置标准值=N/A,并进入下一个通道。
  5. 如果你达到交易#(X+1),将之前的所有交易移回(#1被丢弃,#2变成#1,#X+1变成#X)。
  6. 如果你达到一个交易,其开盘时间>=寻找日期(它不被添加到数组中)。
    • 计算之前添加的交易的标准值#1-#X
    • 记忆标准值
    • 记忆交易前文件指针的位置
    • 转入下一个序列
  7. 如果最后一个序列已被处理。
    • 在序列阵列中运行并找到最佳标准值
    • 转到文件中最佳序列的最后一笔交易所在的位置
    • 从文件中读取一个交易,将其添加到数组中(之前的交易被移位)。
    • 记住文件指针的位置
    • 将交易写到结果文件中
    • Set SequentialDate = 交易结束时间 + 1
    • 我们继续在序列中循环,唯一的条件是数组已经被填满,并从记忆的点开始继续读取。

如果我们设法为X百万个交易分配内存(结构的大小 是事先知道的),那么我们将能够读取一次文件。

如果不是,那么我们就需要在每次返回时将最后一个X交易的读数添加到记住的指针中。然后文件将被多次读取,但仍然是经济的。

序列的结构将是固定的:Nos, Trades[X], Criterion, FilePointer位置。没有什么是不必要的。

剩下的就是编码了 =)

 

什么是更理想的结果。

一个dll还是一个mql计算?

 

是的,在这种形式下,任务是并行的--每次SeekDate 改变时,你可以在序列集的不同部分上同时运行最佳标准的搜索例如,我们把它们分成20个部分,把任务交给20个专家顾问。而他们应该读取文件,找到交易,并只发回最佳序列(№№,标准和文件位置)。

非常感谢你们!

 
ALXIMIKS:

什么是更理想的结果。

dll或仍然是mql来计算?

当然,更好的是mql。而且写一个dll是没有意义的,你也可以在MT中进行并行化。
 

我使用mql没有半年,我可能有点笨,如果我错了请澄清。

Открываем файл, начинаем читать, последовательно заполняя массив сделок первого прохода 

你是否打算为每一个通道做一个单独的磁盘读取?从磁盘上读取10^6次?

单独阅读而不是一次性阅读一整块,就不能有一个坎儿吗?或者说,这里的一切都在最高水平上实现,并有坚实的缓冲区?

如果我们到达一个交易,其开盘时间>= SeekDate(它不会被添加到数组中)

  • Set SeekingDate = 交易结束时间 + 1
  • 我们继续在序列中循环,唯一需要注意的是,数组已经被填满,从存储点继续读取。

我没有看到内存被释放的地方,它一直堆积着。

  • 在序列阵列中运行并找到最佳标准值

为什么要为一个标准器保留整个阵列?你可以在计算新标准时简单地进行比较,并保留适当的标准。

如果你想找到10个最好的标准,最好是做一个有10个标准的数组,用数值填充它,进行排序,然后用二进制搜索 插入下一个标准。

 
ALXIMIKS:

你是否计划对每一次的读取进行单独的磁盘读取?从磁盘读取10^6次?

无论如何,我们将不得不读取整个文件。我们不能一次完成(从头到尾),所以我们必须分片阅读(但我们最终还是会得到整个文件)。

ALXIMIKS

一次读一个片断而不是一次读整个片断,就不能有一个小插曲吗?或者说,这里的一切都在最高水平上实现,并有坚实的缓冲区?

读取一个大块。块的大小是由寻求日期之前的交易数量决定的,这些交易是在一个特定的序列中。

ALXIMIKS

我没有看到内存被释放的地方,它一直堆积着。

内存为一个序列结构的数组分配一次。

序列结构包括:编号,序列中所有交易的结构阵列[X],标准值,文件指针位置

下一步只是填充结构元素(包括交易的数组)。阵列中的交易是移位的,所以内存中每个序列总是只有X个交易。

ALXIMIKS

如果你想找到10个最好的标准,最好是创建一个有10个标准的数组,用数值填充它,对它进行排序,然后用二进制搜索插入下一个标准。

包括用于并联的。

但是从一个包含交易结构数组的结构中消除一个双倍数,在任务框架内并没有什么区别。

 

分享我的研究结果。

二进制缓存文件的读取量为7529MB。

  • 从硬盘:212.3秒(35.46MB/秒)。
  • 从RAM磁盘:88.1秒(85.46MB/秒)。
虽然我有最普通的硬盘(虽然,内存也不快),但很难称得上是宇宙的差异。

结论:使用RAM磁盘读取一个大文件的速度大约是2.5倍。

 

如果文件不是按序列内的交易时间排序,而是按全局(按所有序列)排序,那么就可以采用以下算法。

- 计算一个交易的标准,认为它是一个候选人

- 我们计算在这个交易里面开始的交易的标准,如果我们得到了最好的标准,我们就改变候选人,如果没有,我们就认为候选人被选中,并从其结束的日期开始新的周期。

我们也可以按关闭时间排序--在这种情况下,我们从末尾开始。

很明显,为了计算一个标准,文件必须包含每个交易的序列号。

对这样的文件进行重新排序可能也不是一件有趣的事情,我们可以尝试一下子把它 "正确 "地写入。那就是不要一个一个地生成整个序列,而是为每个序列生成一个事务,并在写入时使用一些具有智能的缓存。当然,对于某些生成算法,这可能是不可接受的。

 
Candid:

如果文件不是按序列内的交易时间排序,而是按全局(按所有序列)排序,那么这样的算法将是可能的。

- 计算交易的标准,将其视为一个候选者

假设我录制了这样一个文件(只是转换当前的文件,即使需要15个小时的电脑时间)。

但随后--在第一点上--出现了一个小插曲。有了这样一个文件,我如何计算序列中最后X个交易的标准?

同样,标准不能一次计算完毕,其参数可能会改变。