Francuz: People, can you share some information? What are you using alignment for?
It all comes in handy in a multi-threaded environment, I see it that way. What's MKL got to do with it? I don't know, the question was asked, so I got stuck.
And in general - these are the basics, a basic understanding is necessary for any decent programmer.
ZS: Well, there are a lot of speed fanatics here, if they start to align everything intelligently, they should fly even faster, in theory at least.
ZS: well there are a lot of speed fans here, if they start to get it right, it should go even faster, in theory at least.
In general, I didn't even expect that:
#define WRONG_ALIGNED
#define CACHE_LINE_SIZE 64struct Data {
#ifdef WRONG_ALIGNED
short bad_pad;
#endif
uint ar[CACHE_LINE_SIZE/sizeof(int)];
};
#import "msvcrt.dll"long memcpy(Data &, Data &, long);
#import
#define getaddr(x) memcpy(x, x, 0)
voidOnStart()
{
Data data[32768];
if (getaddr(data[0])%4 != 0) {
Alert("error");
return;
}
ZeroMemory(data);
int index = int(CACHE_LINE_SIZE - getaddr(data[0]) % CACHE_LINE_SIZE) / sizeof(int) - 1;
srand(GetTickCount());
ulong start_time = GetMicrosecondCount();
for(unsigned i = 0; i < 10000; ++ i) {
int rndnum = rand();
while (++rndnum < 32768)
for (int j = ArraySize(data[rndnum].ar)-1; j >= 0; -- j)
++ data[rndnum].ar[j];
}
Alert(GetMicrosecondCount() - start_time);
for (int j = ArraySize(data[100].ar)-1; j >= 0; -- j)
Print(data[100].ar[j]);
}
/*
WRONG_ALIGNED:
6117940
6104068
6047416
RIGHT_ALIGNED
3341823
2565150
2565150
*/
The code is a little bit overcomplicated - I tried to hit that element which doesn't fit into cache line and bang directly on it, but it failed (it probably could be done if I wanted to, but I got bored), and I didn't change the code much. But this is even more impressive - only one of 16 collapses is done over element not falling into cache line, nevertheless it gives sensible result.
SZY: more objectively in this case to do RIGHT_ALIGNED by inserting two short, instead of removing unique (so we will achieve two updates of cache-line for both cases). The speedup will be more modest, but still about 1.5 times as much.
I took the zigzag from the Metatrader delivery to demonstrate the error. Added additional buffers to the code, taken from my program. No manipulations with additional buffers are intended in this code. They are just to demonstrate the error.
Plotted this zigzag on EURUSD H1 timeframe. Closed the terminal. Deleted all generated time series for EURUSD from the history. I.e. deleted all *.hcc and *.hc files of the EURUSD currency pair. It has been done to ensure the loading of .hcc files and generation of .hc files from a clean sheet.
After the terminal has been started, you will see a lot of artifacts on the EURUSD chart. These artifacts cannot be dealt with.
I am attaching the modified code of the zigzag in the form of text and in the form of a file.
I want to warn you that parameters of the zigzag are specified via #propert.
All other buffers are not set through #propert, because everything, including zigzags buffers, are changed dynamically.
//+------------------------------------------------------------------+//| ZigZag.mq5 |//| Copyright 2009-2017, MetaQuotes Software Corp. |//| http://www.mql5.com |//+------------------------------------------------------------------+#property copyright"2009-2017, MetaQuotes Software Corp."#property link"http://www.mql5.com"#property version"1.00"#property indicator_chart_window#property indicator_buffers29#property indicator_plots17//---- plot Zigzag#property indicator_label17 "Zigzag"#property indicator_type17 DRAW_SECTION#property indicator_color17 Red
#property indicator_style17 STYLE_SOLID#property indicator_width17 1//--- input parametersinputint ExtDepth=12;
inputint ExtDeviation=5;
inputint ExtBackstep=3;
//--- indicator buffersdouble ZigzagBuffer[]; // main bufferdouble HighMapBuffer[]; // highsdouble LowMapBuffer[]; // lowsint level=3; // recounting depthdouble deviation; // deviation in pointsdouble Hmzz1[], Hmzz2[], Hmzz3[], Hmzz4[], Hmzz5[], Hmzz6[], Hmzz7[], Hmzz8[], Hmzz9[], Hmzz10[];
double Lmzz1[], Lmzz2[], Lmzz3[], Lmzz4[], Lmzz5[], Lmzz6[], Lmzz7[], Lmzz8[], Lmzz9[], Lmzz10[];
double nen_ZigZagL[], nen_ZigZagH[];
double ha[], la[], ham[], lam[];
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- indicator buffers mappingSetIndexBuffer(0,Lmzz1,INDICATOR_DATA); // Plot = 0SetIndexBuffer(1,Hmzz1,INDICATOR_DATA);
SetIndexBuffer(2,Lmzz2,INDICATOR_DATA); // Plot = 1SetIndexBuffer(3,Hmzz2,INDICATOR_DATA);
SetIndexBuffer(4,Lmzz3,INDICATOR_DATA); // Plot = 2SetIndexBuffer(5,Hmzz3,INDICATOR_DATA);
SetIndexBuffer(6,Lmzz4,INDICATOR_DATA); // Plot = 3SetIndexBuffer(7,Hmzz4,INDICATOR_DATA);
SetIndexBuffer(8,Lmzz5,INDICATOR_DATA); // Plot = 4SetIndexBuffer(9,Hmzz5,INDICATOR_DATA);
SetIndexBuffer(10,Lmzz6,INDICATOR_DATA); // Plot = 5SetIndexBuffer(11,Hmzz6,INDICATOR_DATA);
SetIndexBuffer(12,Lmzz7,INDICATOR_DATA); // Plot = 6SetIndexBuffer(13,Hmzz7,INDICATOR_DATA);
SetIndexBuffer(14,Lmzz8,INDICATOR_DATA); // Plot = 7SetIndexBuffer(15,Hmzz8,INDICATOR_DATA);
SetIndexBuffer(16,Lmzz9,INDICATOR_DATA); // Plot = 8SetIndexBuffer(17,Hmzz9,INDICATOR_DATA);
SetIndexBuffer(18,Lmzz10,INDICATOR_DATA); // Plot = 9SetIndexBuffer(19,Hmzz10,INDICATOR_DATA);
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(4,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(5,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(6,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(7,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(8,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(9,PLOT_EMPTY_VALUE,0.0);
ArraySetAsSeries(Lmzz1,true);
ArraySetAsSeries(Hmzz1,true);
ArraySetAsSeries(Lmzz2,true);
ArraySetAsSeries(Hmzz2,true);
ArraySetAsSeries(Lmzz3,true);
ArraySetAsSeries(Hmzz3,true);
ArraySetAsSeries(Lmzz4,true);
ArraySetAsSeries(Hmzz4,true);
ArraySetAsSeries(Lmzz5,true);
ArraySetAsSeries(Hmzz5,true);
ArraySetAsSeries(Lmzz6,true);
ArraySetAsSeries(Hmzz6,true);
ArraySetAsSeries(Lmzz7,true);
ArraySetAsSeries(Hmzz7,true);
ArraySetAsSeries(Lmzz8,true);
ArraySetAsSeries(Hmzz8,true);
ArraySetAsSeries(Lmzz9,true);
ArraySetAsSeries(Hmzz9,true);
ArraySetAsSeries(Lmzz10,true);
ArraySetAsSeries(Hmzz10,true);
ArraySetAsSeries(nen_ZigZagH,true);
ArraySetAsSeries(nen_ZigZagL,true);
ArraySetAsSeries(ham,true);
ArraySetAsSeries(lam,true);
ArraySetAsSeries(ha,true);
ArraySetAsSeries(la,true);
PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(5,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(6,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(7,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(8,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(9,PLOT_DRAW_TYPE,DRAW_ZIGZAG);
PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(2,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(3,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(4,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(5,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(6,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(7,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(8,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(9,PLOT_LINE_STYLE,STYLE_SOLID);
PlotIndexSetInteger(0,PLOT_LINE_COLOR, clrDarkOrange);
PlotIndexSetInteger(1,PLOT_LINE_COLOR, clrRoyalBlue);
PlotIndexSetInteger(2,PLOT_LINE_COLOR, clrForestGreen);
PlotIndexSetInteger(3,PLOT_LINE_COLOR, clrSienna);
PlotIndexSetInteger(4,PLOT_LINE_COLOR, clrDodgerBlue);
PlotIndexSetInteger(5,PLOT_LINE_COLOR, clrGreen);
PlotIndexSetInteger(6,PLOT_LINE_COLOR, clrBrown);
PlotIndexSetInteger(7,PLOT_LINE_COLOR, clrMediumBlue);
PlotIndexSetInteger(8,PLOT_LINE_COLOR, clrTeal);
PlotIndexSetInteger(9,PLOT_LINE_COLOR, clrMaroon);
PlotIndexSetInteger(0,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(1,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(2,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(3,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(4,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(5,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(6,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(7,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(8,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(9,PLOT_LINE_WIDTH, 0);
SetIndexBuffer(20,nen_ZigZagH,INDICATOR_DATA); // Plot = 10SetIndexBuffer(21,nen_ZigZagL,INDICATOR_DATA); // Plot = 11PlotIndexSetInteger(10,PLOT_DRAW_TYPE,DRAW_ARROW);
PlotIndexSetInteger(10, PLOT_ARROW, 159);
PlotIndexSetInteger(10,PLOT_LINE_STYLE, STYLE_SOLID);
PlotIndexSetInteger(10,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(10,PLOT_LINE_COLOR, clrMagenta);
PlotIndexSetInteger(11,PLOT_DRAW_TYPE,DRAW_ARROW);
PlotIndexSetInteger(11, PLOT_ARROW, 159);
PlotIndexSetInteger(11,PLOT_LINE_STYLE, STYLE_SOLID);
PlotIndexSetInteger(11,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(11,PLOT_LINE_COLOR, clrMagenta);
SetIndexBuffer(22,ham,INDICATOR_DATA); // Plot = 12SetIndexBuffer(23,lam,INDICATOR_DATA); // Plot = 13PlotIndexSetInteger(12,PLOT_DRAW_TYPE,DRAW_LINE);
PlotIndexSetInteger(12,PLOT_LINE_STYLE, STYLE_DOT);
PlotIndexSetInteger(12,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(12,PLOT_LINE_COLOR, clrGreen);
PlotIndexSetInteger(13,PLOT_DRAW_TYPE,DRAW_LINE);
PlotIndexSetInteger(13,PLOT_LINE_STYLE, STYLE_DOT);
PlotIndexSetInteger(13,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(13,PLOT_LINE_COLOR, clrOrange);
SetIndexBuffer(24,ha,INDICATOR_DATA); // Plot = 14SetIndexBuffer(25,la,INDICATOR_DATA); // Plot = 15PlotIndexSetInteger(14,PLOT_DRAW_TYPE,DRAW_LINE);
PlotIndexSetInteger(14,PLOT_LINE_STYLE, STYLE_DOT);
PlotIndexSetInteger(14,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(14,PLOT_LINE_COLOR, clrGreen);
PlotIndexSetInteger(15,PLOT_DRAW_TYPE,DRAW_LINE);
PlotIndexSetInteger(15,PLOT_LINE_STYLE, STYLE_DOT);
PlotIndexSetInteger(15,PLOT_LINE_WIDTH, 0);
PlotIndexSetInteger(15,PLOT_LINE_COLOR, clrRed);
SetIndexBuffer(26,ZigzagBuffer,INDICATOR_DATA);
SetIndexBuffer(27,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(28,LowMapBuffer,INDICATOR_CALCULATIONS);
PlotIndexSetInteger(16,PLOT_DRAW_TYPE,DRAW_SECTION);
PlotIndexSetInteger(16,PLOT_LINE_STYLE, STYLE_SOLID);
PlotIndexSetInteger(16,PLOT_LINE_WIDTH, 1);
PlotIndexSetInteger(16,PLOT_LINE_COLOR, clrRed);
//--- set short name and digits PlotIndexSetString(16,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set empty valuePlotIndexSetDouble(16,PLOT_EMPTY_VALUE,0.0);
//--- to use in cycle
deviation=ExtDeviation*_Point;
//---return(0);
}
//+------------------------------------------------------------------+//| searching index of the highest bar |//+------------------------------------------------------------------+intiHighest(constdouble &array[],
int depth,
int startPos)
{
int index=startPos;
//--- start index validationif(startPos<0)
{
Print("Invalid parameter in the function iHighest, startPos =",startPos);
return0;
}
int size=ArraySize(array);
//--- depth correction if needif(startPos-depth<0) depth=startPos;
double max=array[startPos];
//--- start searchingfor(int i=startPos;i>startPos-depth;i--)
{
if(array[i]>max)
{
index=i;
max=array[i];
}
}
//--- return index of the highest barreturn(index);
}
//+------------------------------------------------------------------+//| searching index of the lowest bar |//+------------------------------------------------------------------+intiLowest(constdouble &array[],
int depth,
int startPos)
{
int index=startPos;
//--- start index validationif(startPos<0)
{
Print("Invalid parameter in the function iLowest, startPos =",startPos);
return0;
}
int size=ArraySize(array);
//--- depth correction if needif(startPos-depth<0) depth=startPos;
double min=array[startPos];
//--- start searchingfor(int i=startPos;i>startPos-depth;i--)
{
if(array[i]<min)
{
index=i;
min=array[i];
}
}
//--- return index of the lowest barreturn(index);
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
int i=0;
int limit=0,counterZ=0,whatlookfor=0;
int shift=0,back=0,lasthighpos=0,lastlowpos=0;
double val=0,res=0;
double curlow=0,curhigh=0,lasthigh=0,lastlow=0;
//--- auxiliary enumerationenum looling_for
{
Pike=1, // searching for next high
Sill=-1// searching for next low
};
//--- initializingif(prev_calculated==0)
{
ArrayInitialize(ZigzagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
}
//--- if(rates_total<100) return(0);
//--- set start position for calculationsif(prev_calculated==0) limit=ExtDepth;
//--- ZigZag was already counted beforeif(prev_calculated>0)
{
i=rates_total-1;
//--- searching third extremum from the last uncompleted barwhile(counterZ<level && i>rates_total-100)
{
res=ZigzagBuffer[i];
if(res!=0) counterZ++;
i--;
}
i++;
limit=i;
//--- what type of exremum we are going to findif(LowMapBuffer[i]!=0)
{
curlow=LowMapBuffer[i];
whatlookfor=Pike;
}
else
{
curhigh=HighMapBuffer[i];
whatlookfor=Sill;
}
//--- chippingfor(i=limit+1;i<rates_total && !IsStopped();i++)
{
ZigzagBuffer[i]=0.0;
LowMapBuffer[i]=0.0;
HighMapBuffer[i]=0.0;
}
}
//--- searching High and Lowfor(shift=limit;shift<rates_total && !IsStopped();shift++)
{
val=low[iLowest(low,ExtDepth,shift)];
if(val==lastlow) val=0.0;
else
{
lastlow=val;
if((low[shift]-val)>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
{
res=LowMapBuffer[shift-back];
if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
//--- high
val=high[iHighest(high,ExtDepth,shift)];
if(val==lasthigh) val=0.0;
else
{
lasthigh=val;
if((val-high[shift])>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
{
res=HighMapBuffer[shift-back];
if((res!=0) && (res<val)) HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
}
//--- last preparationif(whatlookfor==0)// uncertain quantity
{
lastlow=0;
lasthigh=0;
}
else
{
lastlow=curlow;
lasthigh=curhigh;
}
//--- final rejectionfor(shift=limit;shift<rates_total && !IsStopped();shift++)
{
res=0.0;
switch(whatlookfor)
{
case0: // search for peak or lawnif(lastlow==0 && lasthigh==0)
{
if(HighMapBuffer[shift]!=0)
{
lasthigh=high[shift];
lasthighpos=shift;
whatlookfor=Sill;
ZigzagBuffer[shift]=lasthigh;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
lastlow=low[shift];
lastlowpos=shift;
whatlookfor=Pike;
ZigzagBuffer[shift]=lastlow;
res=1;
}
}
break;
case Pike: // search for peakif(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
{
ZigzagBuffer[lastlowpos]=0.0;
lastlowpos=shift;
lastlow=LowMapBuffer[shift];
ZigzagBuffer[shift]=lastlow;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
lasthigh=HighMapBuffer[shift];
lasthighpos=shift;
ZigzagBuffer[shift]=lasthigh;
whatlookfor=Sill;
res=1;
}
break;
case Sill: // search for lawnif(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
{
ZigzagBuffer[lasthighpos]=0.0;
lasthighpos=shift;
lasthigh=HighMapBuffer[shift];
ZigzagBuffer[shift]=lasthigh;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
lastlow=LowMapBuffer[shift];
lastlowpos=shift;
ZigzagBuffer[shift]=lastlow;
whatlookfor=Pike;
}
break;
default: return(rates_total);
}
}
//--- return value of prev_calculated for next callreturn(rates_total);
}
//+------------------------------------------------------------------+
По завершении установки в меню "Пуск" создается группа программ торговой платформы, а на рабочем столе дополнительно помещается ярлык программы. Используйте их для запуска. Нельзя запускать одновременно две копии платформы из одной директории. Чтобы одновременно запустить несколько копий, установите соответствующее количество программ в разные...
I took the zigzag from the Metatrader delivery to demonstrate the error. Added additional buffers to the code, taken from my program. No manipulations with additional buffers are provided in this code. They are just to demonstrate the error.
Plotted this zigzag on EURUSD H1 timeframe. Closed the terminal. Deleted all generated time series for EURUSD from the history. I.e. deleted all *.hcc and *.hc files of the EURUSD currency pair. It has been done to ensure the loading of .hcc files and generation of .hc files from a clean sheet.
After the terminal has been started, you will see a lot of artifacts on the EURUSD chart. These artifacts cannot be dealt with.
I am attaching the modified code of the zigzag in the form of text and in the form of a file.
I want to warn you that parameters of the zigzag are specified via #propert.
All other buffers are not set through #propert, because everything, including zigzags buffers, are changed dynamically.
Please help terminal developers to fix this bug.
Picture with artifacts:
All buffers need to be initialized.
If there is no value in the buffer on the bar, it must be written explicitly to the buffer. In other words, if the calculated value is to be output to the buffer, write it to the buffer, otherwise write an empty value.
If there is no value in the buffer on the bar, it must be explicitly written in the buffer. I.e., if calculated value should be output to buffer - we write it to buffer, otherwise - we write empty value.
Sorry, I missed the initialisation. I have it in my program but missed it in the example.
Attached is a file with initialization. The effect is the same.
The question to developers remains. Please fix this bug.
-------------
In my opinion, the following happens. When launching the program together with the terminal, the timeseries size is either equal to zero or has some minimal value.
The program is initialized on the existing piece of history. But when the size of timeseries is increased, memory fragments that didn't pass through initialization are being used for buffer arrays. As a result, we have this effect.
I tried to handle this effect using events of the terminal. All the same the artefacts appear for a fraction of a second. And this is not good. Such a program must not be released.
Here is how to fix it. After memory allocation for buffers, you should clear this memory at once. But how can we do it? I haven't found such feature on the terminal application developer's side.
People, share some information. What are you using alignment for?
this is Raccoon-oriented programming!
Alas, you can't do without it ;)
this is Raccoon-oriented programming!
Alas, you can't do without it ;)
I'm aware of that. I'm not asking you to teach me about OOP. I asked who uses alignment for what purpose.
People, can you share some information? What are you using alignment for?
It all comes in handy in a multi-threaded environment, I see it that way. What's MKL got to do with it? I don't know, the question was asked, so I got stuck.
And in general - these are the basics, a basic understanding is necessary for any decent programmer.
ZS: Well, there are a lot of speed fanatics here, if they start to align everything intelligently, they should fly even faster, in theory at least.People, share some information. What are you using alignment for?
Vict:
ZS: well there are a lot of speed fans here, if they start to get it right, it should go even faster, in theory at least.
In general, I didn't even expect that:
The code is a little bit overcomplicated - I tried to hit that element which doesn't fit into cache line and bang directly on it, but it failed (it probably could be done if I wanted to, but I got bored), and I didn't change the code much. But this is even more impressive - only one of 16 collapses is done over element not falling into cache line, nevertheless it gives sensible result.
SZY: more objectively in this case to do RIGHT_ALIGNED by inserting two short, instead of removing unique (so we will achieve two updates of cache-line for both cases). The speedup will be more modest, but still about 1.5 times as much.
By the way, in mql the default value of pack is 1, sort of.
Judging from the previous post, maybe it makes sense to prescribe 8 explicitly to all structures and classes.
I can't get over the error.
I took the zigzag from the Metatrader delivery to demonstrate the error. Added additional buffers to the code, taken from my program. No manipulations with additional buffers are intended in this code. They are just to demonstrate the error.
Plotted this zigzag on EURUSD H1 timeframe. Closed the terminal. Deleted all generated time series for EURUSD from the history. I.e. deleted all *.hcc and *.hc files of the EURUSD currency pair. It has been done to ensure the loading of .hcc files and generation of .hc files from a clean sheet.
After the terminal has been started, you will see a lot of artifacts on the EURUSD chart. These artifacts cannot be dealt with.
I am attaching the modified code of the zigzag in the form of text and in the form of a file.
I want to warn you that parameters of the zigzag are specified via #propert.
All other buffers are not set through #propert, because everything, including zigzags buffers, are changed dynamically.
Please help terminal developers to fix this bug.
Picture with artifacts:
I can't get over the error.
I took the zigzag from the Metatrader delivery to demonstrate the error. Added additional buffers to the code, taken from my program. No manipulations with additional buffers are provided in this code. They are just to demonstrate the error.
Plotted this zigzag on EURUSD H1 timeframe. Closed the terminal. Deleted all generated time series for EURUSD from the history. I.e. deleted all *.hcc and *.hc files of the EURUSD currency pair. It has been done to ensure the loading of .hcc files and generation of .hc files from a clean sheet.
After the terminal has been started, you will see a lot of artifacts on the EURUSD chart. These artifacts cannot be dealt with.
I am attaching the modified code of the zigzag in the form of text and in the form of a file.
I want to warn you that parameters of the zigzag are specified via #propert.
All other buffers are not set through #propert, because everything, including zigzags buffers, are changed dynamically.
Please help terminal developers to fix this bug.
Picture with artifacts:
All buffers need to be initialized.
If there is no value in the buffer on the bar, it must be written explicitly to the buffer. In other words, if the calculated value is to be output to the buffer, write it to the buffer, otherwise write an empty value.
In general, I wasn't even expecting this:
Runs on my own have shown no noticeable difference.
If instead of
Forum on trading, automated trading systems and strategy testing
Bugs, bugs, questions
Vict, 2019.07.09 07:17
Data data[32768];make
There is a 6x slowdown!
All buffers need to be initialised.
If there is no value in the buffer on the bar, it must be explicitly written in the buffer. I.e., if calculated value should be output to buffer - we write it to buffer, otherwise - we write empty value.
Sorry, I missed the initialisation. I have it in my program but missed it in the example.
Attached is a file with initialization. The effect is the same.
The question to developers remains. Please fix this bug.
-------------
In my opinion, the following happens. When launching the program together with the terminal, the timeseries size is either equal to zero or has some minimal value.
The program is initialized on the existing piece of history. But when the size of timeseries is increased, memory fragments that didn't pass through initialization are being used for buffer arrays. As a result, we have this effect.
I tried to handle this effect using events of the terminal. All the same the artefacts appear for a fraction of a second. And this is not good. Such a program must not be released.
Here is how to fix it. After memory allocation for buffers, you should clear this memory at once. But how can we do it? I haven't found such feature on the terminal application developer's side.