Ошибки, баги, вопросы - страница 1593

 

Не баг, но не могу не поделиться 

Пишу

if((!IsRunOnTester() && TimeCurrent() >= D'2016.06.31 23:59'))// для тестировщиков, ограничение работы по времени

 Компилятор выдает варнинг 

invalid date *****.mq4  115 46

Он еще и строковые даты проверяет на правильность даты, я потрясен ) (в июне 30 дней)

 

Видимо это никого это не волнует, но все же напишу еще раз.

Реальная задача: создать массивы общим размером примерно под 100% от свободной памяти, быстро заполнить их числами, произвести расчеты и освободить их.

Пробую получить размер свободной памяти через

int mem_free_mb=(int)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE);

результат : 23987 MB, а физической памяти у меня 12141 MB т.е. в два раза меньше.

Понимаю, что эта цифра для марсиан, но все же верю и пишу скрипт для её тестирования:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
#define PARTS 5

   srand(GetTickCount());
//---
   int mem_free_mb=(int)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE);
   //mem_free_mb=5300;//<--- Столько показывает 'Доступной' в диспетчере задач.
   long mem_for_calc=(long)((double)mem_free_mb*1024*1024);
   long mem_one_part=(long)floor((double)mem_for_calc/PARTS);
   if(mem_one_part>=INT_MAX-1)
      mem_one_part=INT_MAX-1;
//---
   printf("Memory for calc: %0.f MB, parts: %d, part: %0.f MB",mem_for_calc/1024/1024,PARTS,mem_one_part/1024/1024);
   char array1[];
   char array2[];
   char array3[];
   char array4[];
   char array5[];

   int res=ArrayResize(array1,(int)mem_one_part);
   Print("Array1 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",1.0*mem_one_part/1024/1024);

   res=ArrayResize(array2,(int)mem_one_part);
   Print("Array2 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",2.0*mem_one_part/1024/1024);

   res=ArrayResize(array3,(int)mem_one_part);
   Print("Array3 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",3.0*mem_one_part/1024/1024);

   res=ArrayResize(array4,(int)mem_one_part);
   Print("Array4 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",4.0*mem_one_part/1024/1024);

   res=ArrayResize(array5,(int)mem_one_part);
   Print("Array5 Resize: ",res);
   if(res<1)return;
   printf("Reserved: %0.f MB",5.0*mem_one_part/1024/1024);

   uint gtc=GetTickCount();
   for(int i=0;i<mem_one_part;i++)
     {
      char ch=(char)rand();
      array1[i]=ch;
      array2[i]=ch;
      array3[i]=ch;
      array4[i]=ch;
      array5[i]=ch;
     }
//---
   printf("Spent time: %d ms",GetTickCount()-gtc);
  }

Получаю закономерный результат - невозможно распределить массив array3, т.к. память закончилась.

Затем раскомментирую строку, где указываю сколько сейчас доступно:

mem_free_mb=5300;//<--- Столько показывает 'Доступной' в диспетчере задач.

После этого скрипт выполняется успешно.

Не хочу быть назойливым для разработчиков, но для работы с памятью важно знать, сколько доступно.

Сделайте пожалуйста, чтобы можно было это знать через TerminalInfoInteger.

 

Вы в курсе, что в большинстве случаев Вы не сможете получить всю доступную память?

Есть такое понятие - фрагментация памяти. Вы тут решили всю память на 5 фрагментов разделить - а нет у системы ни одного непрерывного фрагмента памяти требуемого Вам размера

 
Slawa:

Вы в курсе, что в большинстве случаев Вы не сможете получить всю доступную память?

Есть такое понятие - фрагментация памяти. Вы тут решили всю память на 5 фрагментов разделить - а нет у системы ни одного непрерывного фрагмента памяти требуемого Вам размера

1. Можно вначале узнать, что физически означает параметр TERMINAL_MEMORY_AVAILABLE ?

2. На счет фрагментов, я думаю, что этим должен заниматься менеждер памяти Windows а не программист.

Мне важно знать сколько я могу использовать в данный момент, например я хочу использовать 50 % от доступной памяти.

Другая реальная задача - это запрос CopyTicks. Если запрашивать больше тиков чем доступной памяти то получаем 'out of memory'.

 
Andrey Voytenko:

Другая реальная задача - это запрос CopyTicks. Если запрашивать больше тиков чем доступной памяти то получаем 'out of memory'.

как вариант, выгрузить данные в файл и брать оттуда необходимыми сегментами
 
coderex:
как вариант, выгрузить данные в файл и брать оттуда необходимыми сегментами

Это для меня медленно. Мне хочется все сделать через память. Собственно это и делается сейчас, только приходится вызывать GlobalMemoryStatusEx и узнавать размер доступной.


	          
 
Andrey Voytenko:

Поддерживаю.  Особенно остро эта проблема встаёт при оптимизации на облачных агентах, о возможностях которых ты вообще ничего не знаешь изначально.  Там определить реальный объём доступной памяти невозможно ни через MQL, ни через WinApi (т.к. вызовы dll запрещены).

Действительно непонятно, какой практический смысл тогда имеет TERMINAL_MEMORY_AVAILABLE ?   Зачем его было вводить, если нам от него ни горячо, ни холодно

 
Andrey Voytenko:

Это для меня медленно. Мне хочется все сделать через память. Собственно это и делается сейчас, только приходится вызывать GlobalMemoryStatusEx и узнавать размер доступной.

Я даже представить не могу, зачем такой большой объем данных анализировать, какой от них толк? Очевидно, что использование будет частным, т.к. не у всех ПК имеют одинаковые с вами ресурсы. Тут точно имеет смысл смотреть в сторону изменения алгоритмов. Попробуйте к примеру определить какой объем тиковой истории по одному инструменту за сутки либо за торговую сессию если это биржа и брать их периодами посуточно либо за каждую сессию.
 
Alexey Navoykov:

Действительно непонятно, какой практический смысл тогда имеет TERMINAL_MEMORY_AVAILABLE ?   Зачем его было вводить, если нам от него ни горячо, ни холодно

ну не все же кто использует данный функционал, крутятся в облаке, а придумывали его не лично для вас :)
 
coderex:
ну не все же кто использует данный функционал, крутятся в облаке, а придумывали его не лично для вас :)

Речь не лично обо мне, эту тему здесь поднял другой человек вообще-то, и про облако там не шло речи.  Если вы сюда зашли потроллить, то прошу делать это где-то в другом месте.