Использование нескольких ядер процессора

 
Использует ли ваша программа несколько ядер процессора, некоторые индикаторы очень сильно тормозят при отрисовке и прокрутке, загружая по максимуму только одно ядро? Например этот индикатор можно взять для тестирования LoongMAx96 https://www.mql5.com/ru/code/65. Очень хотелось бы использовать многоядерные процессоры на полную мощность.
LoongMAx96
LoongMAx96
  • голосов: 10
  • 2010.02.15
  • Loong
  • www.mql5.com
Рисует 96 линий скользящий средних, содержит только 100 строк кода (использует класс CMyBuffer)
 

Да, МетаТрейдер 5 в обязательном порядке использует все ядра процессора. В терминале работает множество параллельных процессов по обработке задач: закачка данных, пересчет индикаторов, отрисовка интерфейса, эксперты, торговля и тд.

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

Но конкретная копия индикатора одновременно не использует несколько ядер. Индикаторы, прикрепленные на один инструмент, обрабатываются последовательно в отдельном потоке. С технической точки зрения каждый финансовый инструмент обсчитывается в своем собственном потоке (это может быть отдельное ядро). Это означает, что индикаторы на EURUSD считаются параллельно индикаторам на GBPUSD и тд.

Чтобы индикаторы не тормозили, их надо писать в экономичном режиме. Иначе неправильно написанные индикаторы будут загружать терминал вне зависимости от мощности и ядерности компьютера.

 
Что можно сделать для распаралеливания задачи при расчете множества средних для одного финансового инструмента в данном случае с LoongMAx96 ?
 
gal писал(а) # :
Что можно сделать для распаралеливания задачи при расчете множества средних для одного финансового инструмента в данном случае с LoongMAx96 ?

Нужно его полностью переписать - он написан без учета экономичного расчета.

Даже больше можно сказать - он написан в режиме "принудительно уничтожить любые ресурсы".

 
Мы его перепишем в правильную сторону.

 
Отлично, будем ждать с нетерпением.
 

Мы внесли некоторые изменения в код индикатора LoongMAx96

в функции OnCalculate лучше копировать не все данные (rates_total), а только те, которые еще не были подсчитаны, т.е. учитывать значение prev_calculated

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- Copy the values of the moving average in the buffer MABuffer
   int copied;
   int ibars;
   for(int i=0; i<iNum; i++)
   {
      copied=MAA[i].mCopyBuffer(prev_calculated,rates_total);
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

функцию CMyBuffer.mCopyBuffer нужно переписать так:

   int  mCopyBuffer(int prev_calculated, int total)
     {
      return CopyBuffer(mhandle,0,0,total-prev_calculated+1,mbuffer);
     }

Второй важный момент связан с огромным количеством данных (за счет множества баров и буферов), которое приходится обрабатывать терминалу, он проявляется при работе с большим количеством баров на графике.

Это значение может быть уменьшено в настройках клиентского терминала:

поэтому в функцию OnInit лучше поставить проверку TerminalInfoInteger(TERMINAL_MAXBARS), и если оно превышает некоторое разумное значение, то лучше завершать работу индикатора до уничтожения ресурсов:

int OnInit()
  {
  int MaxBarsinChart=TerminalInfoInteger(TERMINAL_MAXBARS);
  
  if (MaxBarsinChart>50000)
  {
   Print("Максимальное количество баров на графике:",MaxBarsinChart);
   Print("Для работы нужно уменьшить максимальное число баров до 50000 в настройках и перезапустить терминал");
   return(-1);
  }
.....


 

Большое спасибо, что оперативно откликнулись. К сожалению после модификации программы не удалось увидеть существенного прироста производительности, не смотря на то, что одно ядро загружено полностью, остальные простаивают. Основные тормоза проявляются при прокрутке графика влево или вправо, при этом на скорость существенно влияет размер окна, количество свечей в окне, количество средних линий. Очень сильно начинает тормозить если вместо сплошной линии применить какую-нибудь штриховую.

Я предположил, что проблема со скоростью отрисовки линии, но обнаружил, что когда средние линии остаются за границей видимой области – их не нужно отрисовывать, но это продолжает оказывать такое же влияние на скорость отрисовки графика, на котором нет ни одной средней. Размер экрана (2048*1152).

Чтобы не нагружать расчеты чрезмерно длинной историей, я задаю размер буфера вручную, но он не влияет на скорость прокрутки, а только на занимаемую память. Макс.баров в окне установил в минимальное значение 5000, но это тоже не оказало никакого воздействия на скорость.

Причина обращения: