¡Necesito ayuda! No puedo resolver el problema, me encuentro con limitaciones de hardware - página 15

 

Por fin he descubierto lo que se necesita, espero que esta versión sea la definitiva.

Como se ha dicho Todo es bastante simple para dividir y paralelo, los pasos principales:

1. a. Sería muy útil saber dónde está el principio y el final de cada secuencia (por eso sugerí la última vez escribir sus tamaños en un archivo separado)

б. Puede analizarlos usted mismo, pero en este caso tendrá que volver a leer la siguiente parte del archivo desde el disco para leer la secuencia anterior recortada

A continuación, consideraré la variante 1.a. Probablemente, no es óptima, pero me gusta más.

2. Conociendo los tamaños de las secuencias y el tamaño de la memoria para una parte del archivo (500 mb), podemos calcular el tamaño de la parte del archivo que necesitamos descargar.

3. Paralelamente, calculamos los coeficientes de las secuencias, ya que conocemos el principio y el final de cada una de ellas.

4. El principio y el final de cada secuencia pueden almacenarse en la cola multihilo (llenada mientras se calcula el paso 2)

5. Resultado del cálculo - estructura (matriz de la estructura donde el tiempo y el coeficiente + número de secuencia))

6. Cuando se procesa la mitad del tamaño inicial de la memoria asignada (250 mb), comienza el proceso de reescritura con la formación de la segunda cola con el principio y el final

7. Alcanzado el final de la primera línea, leemos desde la segunda; alcanzado el final de la segunda línea, leemos desde la primera.

8. Puede calcular los coeficientes y leer del archivo simultáneamente.

9. Pero cada resultado del cálculo de los coeficientes deberá ser almacenado, y es mejor fusionarlos de una vez en la respuesta:

tenemos que escribir funciones de fusión: dos secuencias de coeficientes en un subresultado, dos subresultados en un subresultado ligeramente completo

10. El proceso de fusión también puede realizarse en paralelo.

11. ¿Cuándo es el resultado? Cuando se terminen los tamaños de las secuencias leídas desde el archivo de adición, entonces dos pilas quedarán vacías, entonces el cálculo de los coeficientes habrá terminado,

entonces tenemos que esperar a que termine el proceso de fusión de los subresultados (también se puede hacer a través de una cola a prueba de hilos)

y finalmente fusionar el subresultado de los diferentes hilos - resultado.


Aquí hay una variante con la máxima carga de todas las posibles, tal vez algo mejor - me alegraré.

Necesito funciones:

formar una secuencia de coeficientes a partir de una secuencia de entrada

fusión de dos secuencias de coeficientes en un único subresultado (posible pérdida de precisión en este caso)

fusión de dos subresultados en un subresultado ligeramente completo (posible pérdida de precisión en este caso)

 
komposter:

Creo que es posible inventar un mecanismo inteligente de carga parcial, pero hay que inventarlo.

Por ejemplo, en la primera lectura, busque para cada pase la última operación cerrada antes de la fecha de inicio, retroceda y lea X operaciones anteriores, recuerde el punto del archivo donde termina esa operación.

Después de eso, encontrar el primer acuerdo en los resultados, y luego trabajar sólo con los datos frescos: leer el archivo desde el punto deseado a la nueva fecha real, y cada vez que las ofertas de cambio en la matriz (vamos a tener una matriz de tamaño fijo - X elementos).

Esto resolverá el problema de las lecturas múltiples (no lo necesitamos) y de la memoria (sólo si podemos colocar X millones de transacciones).

Sí, eso es lo que hará el algoritmo.

  1. Redimensiona todo el array de ofertas a X elementos.
  2. Set SeekDate = StartDate.
  3. Abrir el archivo, empezar a leer, llenando secuencialmente el array de tratos de la primera pasada.
  4. Si los tratos, correspondientes al paso, han terminado (no hay suficientes tratos X), fije el valor del criterio = N/A y pase al siguiente paso.
  5. Si llega a la operación # (X+1), desplaza todas las operaciones anteriores hacia atrás (el #1 se descarta, el #2 se convierte en #1, #X+1 se convierte en #X).
  6. Si llega a una operación, cuya hora de apertura >= fecha de búsqueda (no se añade a la matriz):
    • Calcular el valor del criterio para las operaciones añadidas anteriormente #1 - #X
    • memorizar el valor del criterio
    • memorizar la posición del puntero del archivo antes del trato
    • Pasar a la siguiente secuencia
  7. Si se ha procesado la última secuencia:
    • Recorrer el conjunto de secuencias y encontrar el mejor valor de Criterio
    • Ir a la posición del archivo donde se encuentra la última operación de la mejor secuencia
    • Leer un acuerdo del archivo, añadirlo a la matriz (los acuerdos anteriores se desplazan)
    • Recuerde la posición del puntero del archivo
    • Escribir el acuerdo en el archivo de resultados
    • Set SequentialDate = Deal close time + 1
    • Continuamos el bucle a través de las secuencias, con la única condición de que las matrices ya estén llenas, y la lectura continúa desde el punto memorizado.

Si conseguimos asignar memoria para X millones de operaciones(el tamaño de la estructura se conoce de antemano), entonces podremos leer el archivo una vez.

Si no es así, entonces tenemos que añadir la lectura de los últimos tratos X en cada retorno al puntero almacenado. Entonces, el archivo se leerá varias veces, pero de forma económica.

La estructura de la secuencia será fija: Nos, Trades[X], Criterion, FilePointer position. No hay nada innecesario.

Todavía hay que codificar =)

 

Cuál es el resultado más deseable:

dll o sigue usando mql para calcular?

 

Sí, en esta forma la tarea es paralela - cada vez que cambiael SeekDate, sepuede ejecutar una búsqueda simultánea del mejor Criterio en diferentes partes del conjunto de secuencias. Por ejemplo, los dividimos en 20 partes y damos la tarea a 20 Asesores Expertos. Y deben leer el archivo, encontrar el acuerdo y devolver sólo la mejor secuencia (№№, Criterio y posición del archivo).

Muchas gracias a todos.

 
ALXIMIKS:

Cuál es el resultado más deseable:

¿dll o todavía mql para calcular?

Mejor mql, por supuesto. Y no tiene sentido escribir una dll, se puede paralelizar en MT también.
 

No llevo medio año con mql, puede que sea un poco tonto, aclara si me equivoco:

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

¿piensa hacer una lectura del disco por separado para cada pase? ¿10^6 veces leído del disco?

¿No puede haber un obstáculo en la lectura individual en lugar de leer un trozo entero de una vez? ¿O todo está implementado al más alto nivel aquí con una sólida amortiguación de sobra?

Si llegamos a una operación cuya hora de apertura es >= SeekDate (no se añade al array):

  • Set SeekingDate = Deal Closing Time + 1
  • Continuamos el bucle a través de las secuencias, con la única salvedad de que las matrices ya se han llenado, y la lectura continúa desde el punto almacenado.

No veo dónde se libera la memoria, se sigue acumulando.

  • Recorrer el conjunto de secuencias y encontrar el mejor valor de Criterio

¿Por qué mantener todo el conjunto para un Criterio? Basta con compararlos al calcular un nuevo criterio y quedarse con el adecuado.

Si quiere encontrar los 10 mejores criterios, es mejor hacer un array de 10 criterios, llenarlo de valores, ordenarlo y luego insertar el siguiente criterio usando la búsqueda binaria.

 
ALXIMIKS:

¿Piensa realizar una lectura del disco por separado para cada pase? ¿Leer 10^6 veces del disco?

De todos modos, tendremos que leer todo el archivo. No podemos hacerlo todo de una vez (de principio a fin), así que tendremos que leer por partes (pero aún así acabaremos con el archivo completo).

ALXIMIKS:

¿No puede haber un inconveniente en leer un trozo a la vez en lugar de leer todo el trozo de una vez? ¿O todo está implementado al más alto nivel aquí con una sólida amortiguación de sobra?

Se lee un trozo. El tamaño del trozo está determinado por el número de transacciones anteriores a la fecha de búsqueda, que se encontraban en una secuencia determinada.

ALXIMIKS:

No veo dónde se libera la memoria, se sigue acumulando.

La memoria se asigna una vez para una matriz de estructuras de secuencia.

La estructura de la secuencia incluye: Nº, Array de estructuras de todas las transacciones de la secuencia [X], Valor del criterio, Posición del puntero del archivo.

El siguiente paso es sólo el llenado de los elementos de la estructura (incluyendo arrays de ofertas). Los tratos en la matriz están desplazados, por lo que siempre hay sólo X tratos de cada secuencia en la memoria.

ALXIMIKS:

Si quiere encontrar los 10 mejores criterios, es mejor crear una matriz de 10 criterios, llenarla de valores, ordenarla y luego insertar el siguiente criterio utilizando la búsqueda binaria.

Incluso para la puesta en paralelo.

Pero la eliminación de un doble de una estructura que contiene una matriz de estructuras de reparto no supone ninguna diferencia en el marco de la tarea.

 

Compartir los resultados de mi investigación.

Archivo binario de caché de 7529 MB de lectura:

  • Desde el disco duro: en 212,3 segundos (35,46 MB/seg)
  • Desde el disco RAM: en 88,1 segundos (85,46 MB/seg)
Es difícil decir que la diferencia sea cósmica, aunque tengo el disco duro más común (aunque, la memoria tampoco es rápida).

Conclusión: la velocidad de lectura de un archivo grande utilizando el disco RAM es de aproximadamente 2,5 veces.

 

Si el archivo estuviera ordenado por tiempo de tratos no dentro de las secuencias, sino globalmente (por todas las secuencias), entonces sería posible el siguiente algoritmo:

- Calcular el criterio para un comercio, considerarlo un candidato

- Calculamos los criterios para las ofertas que se inician dentro de esta oferta, si obtenemos la mejor, cambiamos el candidato, si no lo hacemos, consideramos el candidato seleccionado e iniciamos un nuevo ciclo desde la fecha de su cierre.

También podemos ordenar por tiempo de cierre - en este caso empezamos por el final

Está claro que para el cálculo de un criterio, el archivo debe contener el número de secuencia de cada operación.

La reordenación de un archivo de este tipo probablemente tampoco sea algo divertido, podemos intentar escribirlo "correctamente" de una vez. Es decir, no generar secuencias enteras una a una, sino generar una transacción para cada secuencia y utilizar alguna caché con inteligencia al escribir. Para algunos algoritmos de generación, por supuesto, esto puede ser inaceptable.

 
Candid:

Si el archivo estuviera ordenado por el tiempo de los tratos no dentro de las secuencias, sino globalmente (por todas las secuencias), entonces ese algoritmo sería posible:

- Calcule el criterio para el acuerdo, considérelo un candidato

Supongamos que grabo un archivo de este tipo (sólo convirtiendo el actual, aunque me lleve 15 horas de ordenador).

Pero entonces -en el primer punto- hay un inconveniente. ¿Cómo puedo calcular el Criterio sobre las últimas X operaciones de la secuencia, teniendo dicho archivo?

Una vez más, el criterio no se puede calcular una vez, sus parámetros pueden cambiar.