(int)double veya (double)int gibi toplu dönüşümlerin ateşi gibi ve mat işlemlerinde genellikle int+double'ı karıştırmaya dikkat edin.
Bu, işlemcideki en çılgın ek yükü verir - bu kadar pahalı bir montaj talimatı. Çift sayıyorsanız, içinde saymaya devam edin ve tamsayı türlerine geçiş yapmayın.
cvtsi2sd/cvttsd2si gibi komutlar çok uzundur. " En yavaş x86 talimatı " makalesinde küçük bir ipucu, 2 numaralı kötü adam.
Çok değerli bir makale için teşekkürler.
Ama dürüst olmak gerekirse, neden bu basit senaryoda anlamıyorum:
#define Num 1000000voidOnStart ()
{
double arr[Num];
for ( int i= 0 ;i<Num;i++) arr[i]=( double ) rand ()/( 1 + rand ()% 100 ); // инициализируем массив случайными числами double от 0.0 до 32767.0long sumL= 0 ;
ulong t1= GetMicrosecondCount ();
for ( int i= 0 ;i<Num;i++) sumL+=( long )arr[i]; // сумма long
t1= GetMicrosecondCount ()-t1;
double sumD= 0 ;
ulong t2= GetMicrosecondCount ();
for ( int i= 0 ;i<Num;i++) sumD+=arr[i]; // сумма double
t2= GetMicrosecondCount ()-t2;
Print ( "Сумма long = " + string (sumL)+ ", время суммирования " + string (t1)+ " микросекунд" );
Print ( "Сумма double = " + DoubleToString (sumD)+ ", время суммирования " + string (t2)+ " микросекунд" );
}
double türünden uzuna dönüşümlü bir long toplamı, aynı dizinin dönüşümsüz double toplamından belirgin şekilde daha hızlıdır
İlk olarak, montaj koduna ve son derece basit durumların optimizasyonlarının sonucuna bakmanız gerekir (süpermikrosentetikler uzun süredir yanıltıcıdır). Bir konveyör uygulamasıyla karşılaşmak kolaydır, bu sadece ideal bir durumdur.
İkincisi, çok az kişi nasıl derleneceğini ve şu veya bu kodu çalıştırmanın ne kadar süreceğini garanti edebilir.
Koda ek bir satır/komut eklemek yeterlidir ve hız önemli ölçüde değişir. Gerçek kod/veri L1/L2 önbelleğinden çıkabilir ve bu kadar.
Senin için nasıl çalıştı? Teoriye / süpersentetiklere göre, tamsayı komutlarının hız konusunda yardımcı olacağı, ancak gerçek kodda boşa çıkacağı görülüyor. Onlarca/yüzlerce kat daha fazla kod olduğundan, ardışık düzen yoktur, hesaplamaların tamsayıdan gerçeğe sürekli atlaması ve optimizasyon sınırlıdır.
Canvas'ta uygulanan yüzlerce hareketli ortalamanın ultra hızlı göstergesi.
100 MA satırı (nokta adım 10) - hesaplama ve görüntüleme süresi - 4-7 milisaniye
1000 MA satırı (dönem adım 1) - hesaplama ve görüntüleme süresi - 20-30 milisaniye
Kod fazla test edilmedi. Hatalar olabilir. Yalnızca bir piksel kalınlığında bir çubuk için uygulanır (zorla böyle bir ölçeğe çevrilir). Ayrıca, ekran yenileme hızı optimize edilmemiş. Tüm satırlar hesaplanır ve her onay işareti üzerinde tam olarak görüntülenir.
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164#property indicator_chart_window//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+inputint MA= 1000 ; // максимальный период скользящих среднихinputint stepMa= 10 ; // шаг скользящих среднихdoubleClose [];
long Total;
int Ma;
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+intOnInit ()
{
ChartSetInteger ( 0 , CHART_EVENT_MOUSE_MOVE , true );
ChartSetInteger ( 0 , CHART_SCALE , 0 , 0 );
ChartSetInteger ( 0 , CHART_FOREGROUND , true );
CopyClose ( _Symbol , _Period ,( int )W.Right_bar,W.BarsInWind+Ma- 1 , Close );
Total= SeriesInfoInteger ( _Symbol , _Period , SERIES_BARS_COUNT );
if (Total<(MA+W.BarsInWind)) Ma=( int )Total- 1 -W.BarsInWind; else Ma=MA;
if (Ma<= 0 ) Ma= 1 ;
return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate ( constint rates_total, constint prev_calculated, constint begin, constdouble &price[])
{
CopyClose ( _Symbol , _Period ,( int )W.Right_bar,W.BarsInWind+Ma- 1 , Close );
Print ( "Время формирования кадра = " +( string )(nMA()/ 1000 )+ " миллискунд" );
return (rates_total);
}
//+------------------------------------------------------------------+//| ChartEvent function |//+------------------------------------------------------------------+voidOnChartEvent ( constint id,
constlong &lparam,
constdouble &dparam,
conststring &sparam)
{
if (id== CHARTEVENT_CHART_CHANGE )
{
ChartSetInteger ( 0 , CHART_SCALE , 0 , 0 );
CopyClose ( _Symbol , _Period ,( int )W.Right_bar,W.BarsInWind+Ma- 1 , Close );
Print ( "Время формирования кадра = " +( string )(nMA()/ 1000 )+ " миллискунд" );
}
}
//+------------------------------------------------------------------+ulong nMA()
{
ulong t= GetMicrosecondCount ();
int preY= 0 ;
Canvas.Erase();
double S= 0 ;
for ( int i= 0 ;i<Ma; i++) S+= Close [i];
for ( int Per=Ma;Per> 0 ;)
{
double s=S;
uint Clr=Grad(( double )Per/Ma);
for ( int x= 0 ; x<W.BarsInWind;x++)
{
int Y=( int )(Canvas.Y(s/Per)- 0.5 );
if (x> 0 ) if ( fabs (Y-preY)> 1 ) Canvas.Line(x- 1 ,preY,x,Y,Clr);
else Canvas.PixelSet(x,Y,Clr);
if ((Ma+x)< ArraySize ( Close )) s=s- Close [x+Ma-Per]+ Close [Ma+x]; elsebreak ;
preY=Y;
}
for ( int j= 0 ; j<stepMa; j++) if (Per> 0 ){ S=S- Close [Ma-Per]; Per--;} elsebreak ;
}
Canvas.Update();
returnGetMicrosecondCount ()-t;
}
//+------------------------------------------------------------------+uint Grad( double p)
{
staticuint Col[ 6 ]={ 0xFF0000FF , 0xFFFF00FF , 0xFFFF0000 , 0xFFFFFF00 , 0xFF00FF00 , 0xFF00FFFF };
if (p> 0.9999 ) return Col[ 5 ];
if (p< 0.0001 ) return Col[ 0 ];
p=p* 5 ;
int n=( int )p;
double k=p-n;
argb c1,c2;
c1.clr=Col[n];
c2.clr=Col[n+ 1 ];
return ARGB( 255 ,c1.c[ 2 ]+ uchar (k*(c2.c[ 2 ]-c1.c[ 2 ])+ 0.5 ),
c1.c[ 1 ]+ uchar (k*(c2.c[ 1 ]-c1.c[ 1 ])+ 0.5 ),
c1.c[ 0 ]+ uchar (k*(c2.c[ 0 ]-c1.c[ 0 ])+ 0.5 ));
}
//+------------------------------------------------------------------+
Все функции типа iMA, iAC, iMACD, iIchimoku и т.п., создают в глобальном кеше клиентского терминала копию соответствующего технического индикатора. Если копия индикатора с этими параметрами уже существует, то новая копия не создается, а увеличивается счетчик ссылок на данную копию. Эти функции возвращают хэндл соответствующей копии индикатора...
Çıktı frekansına değil, tuval oluşturma frekansına baktığım ortaya çıktı.
Bunlar birbirinin katı olan farklı sayılardır.
Tuval oluşturma frekansını (çıktı olmadan) ve çıktı frekansını (üretim olmadan) biraz yanlış hesapladığım ortaya çıktı.
İşte daha doğru bir versiyon.
İşlemcimdeki sonuçlar:
Çıkışsız 200 düzleştirilmiş daireden yalnızca bir çerçeve oluşturmak için zaman alırsak, bu, saniyede yaklaşık 500 karelik bir frekansta gerçekleşir.
200 düzleştirilmemiş dairenin çıktısız çerçevelenmesi - saniyede yaklaşık 1000 kare.
Ekranda bir görüntüyü (tuval) görüntüleme (Güncelleme işlevi) işlevinin kendisinin frekansı, saniyede yaklaşık 650 karedir.
Gerçekten harika bir iş çıkardın!
(int)double veya (double)int gibi toplu dönüşümlerin ateşi gibi ve mat işlemlerinde genellikle int+double'ı karıştırmaya dikkat edin.
Bu, işlemcideki en çılgın ek yükü verir - bu kadar pahalı bir montaj talimatı. Çift sayıyorsanız, içinde saymaya devam edin ve tamsayı türlerine geçiş yapmayın.
cvtsi2sd/cvttsd2si gibi komutlar çok uzundur. " En yavaş x86 talimatı " makalesinde küçük bir ipucu, 2 numaralı kötü adam.
Çok değerli bir makale için teşekkürler.
Ama dürüst olmak gerekirse, neden bu basit senaryoda anlamıyorum:
double türünden uzuna dönüşümlü bir long toplamı, aynı dizinin dönüşümsüz double toplamından belirgin şekilde daha hızlıdır
İlk olarak, montaj koduna ve son derece basit durumların optimizasyonlarının sonucuna bakmanız gerekir (süpermikrosentetikler uzun süredir yanıltıcıdır). Bir konveyör uygulamasıyla karşılaşmak kolaydır, bu sadece ideal bir durumdur.
İkincisi, çok az kişi nasıl derleneceğini ve şu veya bu kodu çalıştırmanın ne kadar süreceğini garanti edebilir.
Koda ek bir satır/komut eklemek yeterlidir ve hız önemli ölçüde değişir. Gerçek kod/veri L1/L2 önbelleğinden çıkabilir ve bu kadar.
Senin için nasıl çalıştı? Teoriye / süpersentetiklere göre, tamsayı komutlarının hız konusunda yardımcı olacağı, ancak gerçek kodda boşa çıkacağı görülüyor. Onlarca/yüzlerce kat daha fazla kod olduğundan, ardışık düzen yoktur, hesaplamaların tamsayıdan gerçeğe sürekli atlaması ve optimizasyon sınırlıdır.
MQL4'te herhangi bir türden dizilerin başlatılması neden MQL5'tekinden 10 kat daha yavaş?
MQL4'te herhangi bir türden dizilerin başlatılması neden MQL5'tekinden 10 kat daha yavaş?
Çünkü orada tüm diziler dinamiktir ve dil on kat daha yavaştır.
Canvas'ta uygulanan yüzlerce hareketli ortalamanın ultra hızlı göstergesi.
100 MA satırı (nokta adım 10) - hesaplama ve görüntüleme süresi - 4-7 milisaniye
1000 MA satırı (dönem adım 1) - hesaplama ve görüntüleme süresi - 20-30 milisaniye
Kod fazla test edilmedi. Hatalar olabilir. Yalnızca bir piksel kalınlığında bir çubuk için uygulanır (zorla böyle bir ölçeğe çevrilir). Ayrıca, ekran yenileme hızı optimize edilmemiş. Tüm satırlar hesaplanır ve her onay işareti üzerinde tam olarak görüntülenir.
Canvas'ta uygulanan yüzlerce hareketli ortalamanın ultra hızlı göstergesi.
100 MA satırı (nokta adım 10) - hesaplama ve görüntüleme süresi - 4-7 milisaniye
1000 MA satırı (dönem adım 1) - hesaplama ve görüntüleme süresi - 20-30 milisaniye
harika, standart göstergeler aracılığıyla her şey sıkıca asılırdı
harika, standart göstergeler aracılığıyla her şey sıkıca asılırdı
ve bir kilometrelik kod olurdu ...
belki bu bile sadece bir şablonla yapılabilir. Bir göstergenin gövdesindeki gösterge çizgilerinin sayısıyla ilgili kısıtlamaların farkında değil.
...
Bir göstergenin gövdesindeki gösterge çizgilerinin sayısıyla ilgili kısıtlamaların farkında değil.
Bir sınırlama var. 512'ye kadar gösterge tamponu yapılabilir >>> https://www.mql5.com/en/docs/indicators