Вычислительные ресурсы: память, диск, процессор

Как и все программы, MQL-программы потребляют компьютерные ресурсы, внося свой вклад в расход памяти, места на диске и загрузку процессора терминалом. Учитывая, что терминал сам по себе весьма требователен к ресурсам (в частности, припомним потенциальную загрузку котировок и тиков для множества финансовых инструментов, с многолетней историей), иногда требуется анализировать и контролировать ситуацию на предмет близости доступных лимитов.

MQL5 API предоставляет несколько свойств, позволяющих оценить предельно достижимые и израсходованные ресурсы. Свойства сведены в перечисления ENUM_MQL_INFO_INTEGER и ENUM_TERMINAL_INFO_INTEGER.

Идентификатор

Описание

MQL_MEMORY_LIMIT

максимально возможный объём динамической памяти для MQL-программы в KB

MQL_MEMORY_USED

размер использованной памяти MQL-программой в MB

MQL_HANDLES_USED

количество объектов классов

TERMINAL_MEMORY_PHYSICAL

размер физической оперативной памяти в системе в MB

TERMINAL_MEMORY_TOTAL

размер памяти (физической+файл подкачки, то есть виртуальной), доступной процессу терминала (агента) в MB

TERMINAL_MEMORY_AVAILABLE

размер свободной памяти процесса терминала (агента) в MB, часть TOTAL

TERMINAL_MEMORY_USED

размер памяти, использованной терминалом (агентом) в MB, часть TOTAL

TERMINAL_DISK_SPACE

объем свободной памяти на диске, с учетом возможных квот для папки MQL5/Files терминала (агента), в MB

TERMINAL_CPU_CORES

количество ядер процессора в системе

TERMINAL_OPENCL_SUPPORT

версия поддерживаемой OpenCL в виде 0x00010002 = 1.2; "0" означает, что OpenCL не поддерживается

Максимальный объем памяти, доступный MQL-программе, описывается свойством MQL_MEMORY_LIMIT. Это единственное свойство из перечисленных, использующее килобайты (Kb). Все остальные возвращаются в мегабайтах (Mb). Как правило, MQL_MEMORY_LIMIT равно TERMINAL_MEMORY_TOTAL, то есть вся имеющаяся на компьютере память по умолчанию может быть выделена одной MQL-программе. Однако терминал, в особенности его облачная реализация для MetaTrader VPS, и облачные агенты тестирования могут ограничивать размер памяти для отдельной MQL-программы. Тогда MQL_MEMORY_LIMIT будет существенно меньше TERMINAL_MEMORY_TOTAL.

Поскольку Windows обычно создает файл подкачки, равный по размеру физической памяти (ОЗУ), свойство TERMINAL_MEMORY_TOTAL может в 2 раза превышать TERMINAL_MEMORY_PHYSICAL.

Вся доступная виртуальная память TERMINAL_MEMORY_TOTAL делится между использованной (TERMINAL_MEMORY_USED) и еще свободной (TERMINAL_MEMORY_AVAILABLE).

К книге прилагается скрипт EnvProvision.mq5, в котором в журнал выводятся все указанные свойства.

void OnStart()
{
   PRTF(MQLInfoInteger(MQL_MEMORY_LIMIT)); // Kb!
   PRTF(MQLInfoInteger(MQL_MEMORY_USED));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_PHYSICAL));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_TOTAL));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_USED));
   PRTF(TerminalInfoInteger(TERMINAL_DISK_SPACE));
   PRTF(TerminalInfoInteger(TERMINAL_CPU_CORES));
   PRTF(TerminalInfoInteger(TERMINAL_OPENCL_SUPPORT));
   
   uchar array[];
   PRTF(ArrayResize(array1024 * 1024 * 10)); // выделяем 10 Mb
   PRTF(MQLInfoInteger(MQL_MEMORY_USED));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));
   PRTF(TerminalInfoInteger(TERMINAL_MEMORY_USED));
}

После первичного вывода свойств мы распределяем массив на 10 Mb, и затем снова проверяем память. Пример результата приведен ниже (у вас будут свои значения).

MQLInfoInteger(MQL_MEMORY_LIMIT)=8388608 / ok
MQLInfoInteger(MQL_MEMORY_USED)=1 / ok
TerminalInfoInteger(TERMINAL_MEMORY_PHYSICAL)=4095 / ok
TerminalInfoInteger(TERMINAL_MEMORY_TOTAL)=8190 / ok
TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE)=7842 / ok
TerminalInfoInteger(TERMINAL_MEMORY_USED)=348 / ok
TerminalInfoInteger(TERMINAL_DISK_SPACE)=4528 / ok
TerminalInfoInteger(TERMINAL_CPU_CORES)=4 / ok
TerminalInfoInteger(TERMINAL_OPENCL_SUPPORT)=0 / ok
ArrayResize(array,1024*1024*10)=10485760 / ok
MQLInfoInteger(MQL_MEMORY_USED)=11 / ok
TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE)=7837 / ok
TerminalInfoInteger(TERMINAL_MEMORY_USED)=353 / ok

Обратите внимание, что общая виртуальная память (8190) равна удвоенной физической (4095). Доступный для скрипта объем памяти 8388608 Kb практически равен всей памяти 8190 Mb. Свободная (7842) и занятая (348) системная память в сумме также дают 8190.

Если до выделения памяти под массив MQL-программа занимала 1 Mb, то после выделения — уже 11 Mb. При этом объем памяти, занятой терминалом увеличился всего на 5 Mb (с 348 до 353), поскольку некоторые ресурсы были зарезервированы заранее.