Implementaciones alternativas de funciones/enfoques estándar - página 11

 
Nikolai Semko:
¿Puede enviarme el enlace, por favor?

No lo guardé. Mencionado en el foro aquí. Yo mismo busqué en los motores de búsqueda.

Вопрос к сообществу программистов по поводу авторства
Вопрос к сообществу программистов по поводу авторства
  • 2017.11.24
  • www.mql5.com
Общее обсуждение: Вопрос к сообществу программистов по поводу авторства
 
fxsaber:

No lo guardé. Mencionado en el foro aquí. Busqué en los motores de búsqueda yo mismo.

Lo he visto. Todo es muy primitivo sin la mezcla de colores de los píxeles.
Es que todo lo que me encontré en los foros era de nivel de parvulario. Y ya estoy en el quinto grado.
 
Nikolai Semko:
Es que todo lo que encontré en los foros era de nivel de parvulario. Y ya estoy en el quinto grado.

Obviamente, todas estas motos han sido reconstruidas muchas veces. Incluso se publicaron libros, hasta implementaciones de asm.

Hoy en día es difícil encontrar lo básico, ya que casi todo el mundo utiliza APIs relevantes para todas las ocasiones.

Así que sólo tienes que registrarte en los foros y preguntar por ahí.

 
fxsaber:

Obviamente, todas estas motos han sido reconstruidas muchas veces. Incluso se han publicado libros, hasta las implementaciones de asm.

Ahora es difícil encontrar lo básico, ya que casi todo el mundo utiliza las APIs pertinentes para todas las ocasiones.

Así que sólo tienes que registrarte en los foros y preguntar.

Esa es la cuestión: es difícil. De todos modos, no pude encontrarlo. Tal vez no estaba buscando lo suficiente. En los foros, todo el mundo te enviará a las bibliotecas cerradas estándar y se preguntará por qué lo necesitas, cuando todo está disponible. Por supuesto, no me preocuparía si escribiera en Java, JavaScript y similares. o si el mercado no era necesario.
Vale, ya me he acostumbrado a estar orgullosamente solo en este asunto por ahora. Además, no tengo prácticamente ningún punto en blanco en la comprensión de casi cualquier aplicación en esta dirección. Y, por otro lado, he adquirido algunas habilidades únicas.
 
pavlick_:

¿Por qué no utiliza LONG_MAX/MIN? De alguna manera se vería más decente. Se ve bien, creo. He reproducido tus pruebas con gcc (con mínimas modificaciones, claro, el compilador es el muy antiguo 5.4.0, lo que tenía a mano):


Bueno, sí, no es agradable. PeroLONG_MAX= 9223372036854775807 es más que 9007199254740992. Y la forma hexadecimal de este número - 0x20000000000000 se reprueba porque debe ser sólo para el tipo ulong. Ni siquiera sé cómo aclararlo. No puedo escribir (ulong)(1<<53) porque es una operación que requiere mucho tiempo.

El tipo double comienza a contener enteros sin partes fraccionarias no desde el valorLONG_MAX sino desde la máxima mantisa posible. Pero se permiten 53 bits para la mantisa, es decir, 2^53=9007199254740992.

pavlick_:

Su código de sincronización falla - la salida está en milisegundos (no nano), y todavía no entiendo por qué necesitamos menos t0.

t0 es el tiempo del ciclo completo de 1000000 pases de la suma del doble primo

mientras que t es el tiempo del mismo ciclo de suma de los mismos valores dobles, pero pasado por las funciones ceil, ceil, round etc.

He partido de la lógica de que la diferencia (t-t0) es el tiempo neto empleado en estas funciones.

Por supuesto, sólo se puede conseguir una mayor objetividad realizando varias mediciones.

- En la nano se calcula sobre la base del tiempo que se tarda en realizar una función entre 1.000.000. Exactamente en nano es correcto.

pavlick_:

Ejecuté sus pruebas en gcc (con mínimas modificaciones, por supuesto, el compilador es muy viejo 5.4.0, lo que estaba a la mano):

1. Compilación con -O3.

2. Compilación con -Ofast

Así que resulta. ¿Que el código MQL5 compilado se ejecuta más rápido que incluso Ofast? Es difícil de creer. Debe haber tenido un compilador de 32 bits allí.
 
Nikolai Semko:

No escribir (ulong)(1<<53), pues ya es una operación que consume tiempo.

Esta operación no consume tiempo, como todas las operaciones con constantes, incluidas las cadenas.

input long l = (ulong)1 << 53;
input string s = (string)__DATETIME__ + __FILE__;
 
fxsaber:

Esta operación es intemporal como todas las constantes, incluidas las cadenas.

¡Vaya! ¡Genial! Gracias. Y yo pensaba que siempre cuenta. Sí, bueno, es lógico, ya se puede calcular en tiempo de compilación.
Bueno, eso es todo entonces:

double Ceil (double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
2018.08.26 18:04:07.638 TestRound (EURUSD,M1)   Время цикла без округления = 1.302 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 18:04:07.642 TestRound (EURUSD,M1)   Время выполнения функции ceil =  2.389 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.644 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  0.223 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.648 TestRound (EURUSD,M1)   Время выполнения функции floor = 2.884 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.649 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.122 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.654 TestRound (EURUSD,M1)   Время выполнения функции round = 3.413 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.222 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

Sin embargo, sería más correcto escribirDBL_MANT_DIG en lugar de 53

double Ceil (double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

Caso de ganancia mínima si todos los valores del doble son fraccionarios.

2018.08.26 18:20:35.408 TestRound (EURUSD,M1)   Время выполнения функции sqrt = 1.083 наносекунд, сумма = 81969849.90928555
2018.08.26 18:20:35.413 TestRound (EURUSD,M1)   Время выполнения функции ceil =  3.579 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.416 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  1.249 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.422 TestRound (EURUSD,M1)   Время выполнения функции floor = 3.931 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.424 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.513 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.427 TestRound (EURUSD,M1)   Время выполнения функции round = 1.519 наносекунд, Контрольная сумма = 5249992896.0
2018.08.26 18:20:35.429 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.571 наносекунд, Контрольная сумма = 5249992896.0
Archivos adjuntos:
TestRound.mq5  11 kb
 
Nikolai Semko:
Así que resulta. ¿Que el código MQL5 compilado funciona más rápido que incluso Ofast? Me resulta difícil creer que debe tener un compilador de 32 bits.

He quitado el menos t0 de todo (pensé que era algún tipo de error) y mi salida tiene todo el bucle medido, no una sola pasada. Si convertimos a su forma de salida en nanosegundos por iteración (en la primera línea "Cycle time without rounding" - tenemos la misma forma de contar), obtenemos:

-O3
Время цикла без округления = 1.099 наносекунд, сумма = 1.15583114 e+23
-Ofast
Время цикла без округления = 0.552 наносекунд, сумма = 1.15583114 e+23

No hay mucha aceleración en gcc (y aún más lento en -Ofast). En mcc hay un aumento de velocidad significativo a juzgar por tu prueba, pero:

tienes 985'651 de 1'000'000 es decir, casi todas las iteraciones satisfacen la condición x < MIN || x > MAX.


-Ofast desactiva todas las comprobaciones inf/nan, la configuración de errno, es decir, se deja el redondeo desnudo en la fpu. Y este redondeo desnudo no puede ser derrotado por una simple comparación de x < MIN || x > MAX.

 
pavlick_:

No hay mucha aceleración en gcc (y aún más lento en -Ofast). En µl es significativo.

Sin embargo, es difícil decirlo. Tiramos t0 por buenas cifras y obtuvimos 20 veces de diferencia. Incluso un mínimo código adicional en forma de bucle (+t0) hace que el resultado sea bonito en varias decenas de veces a menos atractivo en unas dos veces. ¿Y qué decir si no es sólo un bucle sino un algoritmo real que hace algo útil? La diferencia no será visible en absoluto, se colgará en algún lugar muy posterior al punto decimal y apenas se convertirá en un cuello de botella. En una aplicación real la recogida de mutex, las barreras de la cpu, la asignación de memoria son mucho más costosas que el redondeo. En definitiva, no merece la pena la apuesta, en mi opinión.

 
pavlick_:

Sí, la diferencia no será visible en absoluto, estará en algún lugar después del punto decimal y es poco probable que sea un cuello de botella. En una aplicación real tomar mutex, barreras de cpu, asignación de memoria son mucho más costosos que el redondeo. En definitiva, no merece la pena la apuesta, en mi opinión.

Esto es cierto el 99% de las veces, sí.

Antes de optimizar, debe asegurarse de que tiene algo que optimizar.

En mi práctica sólo recuerdo un caso en el que mi propia aplicación de la atof fue realmente útil. Aunque a mí me pareció que sí.

Y debes tener en cuenta que cualquier optimización (excepto ***) no es gratuita.

Razón de la queja: