Новая версия платформы MetaTrader 5 build 2007: Экономический календарь, MQL5-программы в виде сервисов - страница 24

 
Slava:

Все локальные переменные распределяются на стеке.

Для каждой функции отводится место на стеке, необходимое для размещения локальных переменных. Эта память освобождается при завершении функции. Если из данной функции производится вызов другой функции, то на стеке отводится место под локальные переменные этой другой функции. При неконтролируемой рекурсии стек исчерпывается очень быстро.

Размер стека MQL-программы заранее ограничен, но не может превышать 64 мегабайта. Если для локальных переменных необходимо более 4 килобайт, то вызывается специальная системная функция _chkstk, которая обеспечивает подгрузку необходимого количества страниц физической памяти в адресное пространство процесса. Вы как любитель замерять время попробуйте измерить время вызова функции, имеющей менее 4к локальных переменных и более 4к (более 8к, более 16к и тд). Узнаете много нового.

Спасибо за подробности. Сделал замеры

#define BENCH(A)                                                               \
{                                                                              \
  const ulong _StartTime = GetMicrosecondCount();                              \
  A;                                                                           \
  Print("Time[" + #A + "] = " + (string)(GetMicrosecondCount() - _StartTime)); \
}

#define KILOBYTE 1024

// Создаем функцию с локальными переменными > A килобайт
#define MACROS(A)                      \
  int f##A()                           \
  {                                    \
    char Array[A * KILOBYTE] = {0};    \
    int Sum = 0;                       \
                                       \
    for (int i = 0; i < KILOBYTE; i++) \
      Sum += Array[i];                 \
                                       \
    return(Sum);                       \
  }

typedef int(*FUNC)( void );

// Вызываем много раз функцию
void Bench( const FUNC Func )
{
  int Sum = 0;
  
  for (int i = 0; i < 100000; i++)
    Sum += Func();
    
  Print(Sum);
}

// Задали функции
MACROS(4)
MACROS(8)
MACROS(16)
MACROS(32)
MACROS(64)

#define BENCH2(A) BENCH(Bench(A));

void OnStart()
{
  // Замеряем вызовы
  BENCH2(f4)
  BENCH2(f8)
  BENCH2(f16)
  BENCH2(f32)
  BENCH2(f64)
}


Замедления не увидел

0
Time[Bench(f4)] = 31080
0
Time[Bench(f8)] = 31082
0
Time[Bench(f16)] = 31094
0
Time[Bench(f32)] = 31054
0
Time[Bench(f64)] = 24866


ЗЫ Попытался обойти оптимизацию компилятора. Не знаю, вышло или нет.

 

1. 100 тысяч итераций - это очень мало.

2. При вызове одной и той же единственной функции в цикле вся работа будет произведена на первой итерации. У Вас даже содержимое локальных переменных будет оставаться от предыдущего вызова.

3. Замер сделан неправильно. Начало замера - до начала цикла, конец - после окончания цикла.

 
Slava:

1. 100 тысяч итераций - это очень мало.

2. При вызове одной и той же единственной функции в цикле вся работа будет произведена на первой итерации. У Вас даже содержимое локальных переменных будет оставаться от предыдущего вызова.

Ну а как тогда замер произвести?! Там и суммирование и распринтовка. Компилятор должен все честно посчитать.

 
fxsaber:

Ну а как тогда замер произвести?! Там и суммирование и распринтовка. Компилятор должен все честно посчитать.

Начало замера - до начала цикла, конец - после окончания цикла.

 
Slava:

Начало замера - до начала цикла, конец - после окончания цикла.

Так и сделано.

 
fxsaber:

Так и сделано.

Да, увидел.
 

Я создал простой сервис (Сервисы в Навигаторе + Вставка):

 //+------------------------------------------------------------------+ 
 //|                                                     Test_001.mq5 | 
 //|                                                            Calli | 
 //|                              https://www.mql5.com/de/users/gooly | 
 //+------------------------------------------------------------------+ 
 #property  service
 #property  copyright "Calli" 
 #property  link        "https://www.mql5.com/de/users/gooly" 
 #property  version    "1.00" 
 //+------------------------------------------------------------------+ 
 //| Service program start function                                   | 
 //+------------------------------------------------------------------+ 
 void OnStart ()
  {
 //--- 
   //Sleep(100); 
  }
 //+------------------------------------------------------------------+ 

Я могу запустить его с помощью Add Service (почему бы не запустить Service в соответствии со следующими пунктами в меню «Start All», «Stop All»?)

Но я не могу остановить его, используя «Стоп» - только «Удалить» останавливает его, но напоминает мне, что меню удаляют файлы .ex5 и mq5?

Кроме того - из-за отсутствия (прокомментированного) Sleep - я ожидал, что загрузка процессора составит 100% - но ничего?

 
Carl Schreiber:

Я создал простой сервис (Сервисы в Навигаторе + Вставка):

Я могу запустить его с помощью Add Service (почему бы не запустить Service в соответствии со следующими пунктами в меню «Start All», «Stop All»?)

Но я не могу остановить его, используя «Стоп» - только «Удалить» останавливает его, но напоминает мне, что меню удаляют файлы .ex5 и mq5?

Кроме того - из-за отсутствия (прокомментированного) Sleep - я ожидал, что загрузка процессора составит 100% - но ничего?

void OnStart()
  {
   Print("service started");
   while(!IsStopped())
     {
      Sleep(0);
     }
   Print("service stopped");
  }
 
Andrey Khatimlianskii:

Ошибка уже исправлена. Ждите обновления.

Большое спасибо.


Тот факт, что ObjectDelete является дорогостоящим процессом,

Если событие OnDeinit прервано более чем на 2,5 секунды

Какие отношения остаются в задаче

Хотя это неизвестно,

Я хотел бы ждать обновлений.


Однако, как инструмент для зарабатывания денег, это неудобно.


 
Alexey Kozitsyn:

А сколько ждать разработчики не уточняли?

К сожалению, сроков не озвучили, я спрашивал.