Указатели требуют дополнительной проверки безопасности, что дает оверхед. Это основа управляемого языка.
Не надо использовать хакерские методы в циклах for - так вы портите компилятору шаблон оптимизации циклов/векторизации и в рабочих условиях получаете код хуже. При этом надо учитывать, что есть немалый шанс самообмана на усеченной синтетике бенчмарков, где некоторые хакерские методы могут показать фейковое улучшение.
Мы постоянно в поиске более быстрых решений и идеи у нас есть, в данный момент прорабатываем решение.
К сожалению, объекты в указатели преобразовать можно, а в обратном направлении - нет.
У меня получилось ускорить указатели, добавив двухстороннее "преобразование".
class TICKS_ARRAY
{
public:
MqlTick Ticks[];
};
template <typename T>
int Func( T &TicksArray[] )
{
int ResCount = 0;
constint Amount = ArraySize(TicksArray);
int Count = 0;
int Size[];
bool Res[];
int Pos[];
ArrayResize(Pos, Amount);
ArrayInitialize(Pos, 0);
for (uint i = ArrayResize(Res, ArrayResize(Size, Amount)); (bool)i--;)
{
Size[i] = ArraySize(TicksArray[i].Ticks);
if (Res[i] = Size[i])
Count++;
}
while (Count)
{
uint Index;
for (int i = 0; i < Amount; i++)
if (Res[i])
{
ResCount += (bool)TicksArray[i].Ticks[Pos[i]].time_msc;
Index = i;
}
if (!(Res[Index] = (++Pos[Index] != Size[Index])))
Count--;
}
return(ResCount);
}
// "Преобразует" указатели в объекты и обратно.int Hack( TICKS_ARRAY* &PtrArray[] )
{
TICKS_ARRAY TicksArray[];
constint Size = ArrayResize(TicksArray, ArraySize(PtrArray));
for (int i = 0; i < Size; i++)
ArraySwap(TicksArray[i].Ticks, PtrArray[i].Ticks);
constint Res = Func(TicksArray);
for (int i = 0; i < Size; i++)
ArraySwap(TicksArray[i].Ticks, PtrArray[i].Ticks);
return(Res);
}
#define BENCH(A) \
{ \
constulong StartTime = GetMicrosecondCount(); \
A; \
Print(#A + ": " + (string)(GetMicrosecondCount() - StartTime) + " mcs."); \
}
voidOnStart()
{
TICKS_ARRAY TicksArray[]; // Массив тиковых массивов.
TICKS_ARRAY* PtrArray[]; // Массив указателей на объекты тиковых массивов.// Заполнили массив объектов.for (uint i = ArrayResize(TicksArray, 20); (bool)i--;)
ArrayResize(TicksArray[i].Ticks, 1e6);
// Заполнили массив указателей.for (uint i = ArrayResize(PtrArray, ArraySize(TicksArray)); (bool)i--;)
PtrArray[i] = &TicksArray[i];
Func(PtrArray); // РазогревPrint("Bench...");
BENCH(Func(TicksArray)); // Func(TicksArray): 599315 mcs.
BENCH(Func(PtrArray)); // Func(PtrArray): 1105295 mcs.
BENCH(Hack(PtrArray)); // Hack(PtrArray): 599608 mcs.
}
С указателями скорость стала такой же, как с объектами!
Получилась хорошая демонстрация, что соответствующее улучшение компилятора может дать существенный рост производительности. В данном случае почти в два раза при использовании указателей.
Просьба рассмотреть возможность файловых операций не только в песочнице (Read/Write: MQL5\Files\*.*), но и в тестерном кеше (Read: Tester\cache\*.tst, *.opt).
Ilyas #:
Что же Вы, то используете 3 параметр, то нет:
Пытался разобраться, как бесплатно (без физического перераспределения) понизить размерность массива, если reserve_size не был ранее задан.
Работаю с большим количеством тиков. Как это делать экономно по памяти?
Выделил проблемный участок кода.
Так зачем физически перестраивать при понижении размерности? Нужно же только счетчик количества элементов массива уменьшить!
Тогда кусок памяти не освободится.
Если хотите работать быстро, то используйте указанный мною метод ведения рядом собственного счетчика рабочих записей в массиве.
ЗЫ Чтобы сохранить старое поведение в песочнице, приходится использовать такой костыль.
Спасибо, пригодилось.
b4240, получил замедление в 1.5 раза своих расчетов после перехода с объектов на их указатели.
Более-менее лаконично удалось воспроизвести на таком примере.
Не может же быть такого, чтобы в тяжелых расчетах нужно было бы отказываться от использования указателей?!
Строка для поиска: Oshibka 098.
b4240, получил замедление в 1.5 раза своих расчетов после перехода с объектов на их указатели.
Более-менее лаконично удалось воспроизвести на таком примере.
Не может же быть такого, чтобы в тяжелых расчетах нужно было бы отказываться от использования указателей?!
Строка для поиска: Oshibka 098.
К сожалению, безопасность не бывает бесплатной.
Мы постоянно в поиске более быстрых решений и идеи у нас есть, в данный момент прорабатываем решение.
Указатели требуют дополнительной проверки безопасности, что дает оверхед. Это основа управляемого языка.
Не надо использовать хакерские методы в циклах for - так вы портите компилятору шаблон оптимизации циклов/векторизации и в рабочих условиях получаете код хуже. При этом надо учитывать, что есть немалый шанс самообмана на усеченной синтетике бенчмарков, где некоторые хакерские методы могут показать фейковое улучшение.
А что означает эта ошибка и как с ней бороться (перевести я смог :))? Только сейчас заметил в 4240. Раньше все ок работало...
Такое ограничение останется?
Это может быть связано с моим железом? Я недавно настройки VM подкручивал, правда все в сторону увеличения памяти и CPU...
Мы постоянно в поиске более быстрых решений и идеи у нас есть, в данный момент прорабатываем решение.
К сожалению, объекты в указатели преобразовать можно, а в обратном направлении - нет.
У меня получилось ускорить указатели, добавив двухстороннее "преобразование".
С указателями скорость стала такой же, как с объектами!
Получилась хорошая демонстрация, что соответствующее улучшение компилятора может дать существенный рост производительности. В данном случае почти в два раза при использовании указателей.
Просьба рассмотреть возможность файловых операций не только в песочнице (Read/Write: MQL5\Files\*.*), но и в тестерном кеше (Read: Tester\cache\*.tst, *.opt).
Библиотеки чтения tst/opt-форматов.
Сейчас для чтения этих файлов приходится подключать WinAPI, либо делать mklink, чтобы Маркет-продукты наделить доп. функционалом.
Строка для поиска: Uluchshenie 089.