В среде QUIK скрипты выполняются в несколько раз дольше, чем в командной строке. Вот такой скрипт
Код
function main()
print = message or print
local abs = math.abs
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
t = os.clock() - t
print(string.format('%0.1f', t))
end
if not message then main() end
в командной строке выполняется 3.5 сек, в QUIK - 8.8 сек. В 2.5 раза дольше! Почему так?
PS: ЦП: 2 ядра, 4 логических процессора.
Надо делать так, как надо. А как не надо - делать не надо.
потому что в первом случае, виртуальная машина запускается отдельным потоком внутри процесса QUIK-а у которого и так полно потоков и поболее приоритетных чем твой скрипт и во втором случае - скрипт запускается в однопоточном процессе ("из командной строки" - это я так понимаю из интерпретатора LUA).
Кроме того, количество ядер - абсолютно никак не влияет на QUIK - бо как он, как уже писалось на форуме - не использует все преимущества многоядерности, а целиком полагается в распределении нагрузки на ОС.
чем больше на графиках наложено индикаторов - тем дольше выполняется скрипт (вне зависимости от того, что он мол де - находится "в майне")
чем больше открыто графиков и окон в квике - тем дольше выполняются скрипты. ЭТО ПОЗОРНЫЙ ФАКТ о котором так любят умалчивать так называемые "разработчики"
стОит поводить окном любой таблицы или графика в QUIK-е - скрипты - ожидаемо начинают притормаживать.
Правильный ответ в данном случае: Потому что в quik Lua собрана с поддерхкой многопоточности. Разница - это накладные расходы на синхронизацию доступа к хранилищу переменных (сделано в Lua надёжно, но не очень эффективно)
Мда... Двухпоточность в QLua работает действительно неэффективно: Вот сейчас запустил одновременно три скрипта в QUIK. Общее время работы составило 12.9 сек, что больше, чем при последовательном их запуске через консоль (3.5+3.5+3.6=10.6 сек). Таким образом, выигрыша в производительности от многопоточной схемы работы в QUIK, действительно, не наблюдается. Единственный плюс - то, что интерфейс не зависает при работе длительных циклов в main.
Надо делать так, как надо. А как не надо - делать не надо.
тот самый написал: я уже приводил 3 примера: чем больше на графиках наложено индикаторов - тем дольше выполняется скрипт (вне зависимости от того, что он мол де - находится "в майне") чем больше открыто графиков и окон в квике - тем дольше выполняются скрипты. ЭТО ПОЗОРНЫЙ ФАКТ о котором так любят умалчивать так называемые "разработчики" стОит поводить окном любой таблицы или графика в QUIK-е - скрипты - ожидаемо начинают притормаживать.
Выходит что луа машина в квике крутится в потоке его gui? Но это же очень плохо как для самого квика так и для сриптов...
swerg написал: Двухпоточность рабатает отлично. Поток main() не мешает основному потоку А время - понятные накладные расходы.
Разве что не мешает... Пока не задействуешь потокобезопасные функции QLua. Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно. А по факту в QUIK накладные расходы слишком высоки.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно.
как только QUIK наконец начнёт импортировать функции вида: SetThreadAffinityMask SetThreadIdealProcessor
тогда и только тогда он хоть на чуточку приблизится к поддержке многоядерности.
Старатель написал: Разве что не мешает... Пока не задействуешь потокобезопасные функции QLua. Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно.
вы как бы правы, но кто говорил про многопоточность? Ну и потом: запустите ваши скрипты отдельными скриптами в quik, и функции main будут работать паралллельно (кстати, надо попробовать)
Цитата
Старатель написал: А по факту в QUIK накладные расходы слишком высоки.
это откуда вывод про слишком? У вас есть другое приложение, на котором вы можете поставить аналогиный эксперимент?
swerg написал: всех,кто имеет удовольствие читать твою ахинею.
а ты тут за всех, что ль уже взялся говорить, высерок?
Цитата
swerg написал: Запрос фактов забавно слышать от того, кто их не приводит
и мне тоже "забавно" слышать "излияния" от такого чмошника, как ты... Заикнулся про то, что есть полностью скаченный старый форум, а потом, как су ка последняя язык в ж пу засунул.... чмо ты и есть чмо
Вопрос разработчикам: верно ли, что в QUIK, как таковой, многопоточности нет? Да, есть два потока: основной и main. Но в каждый момент времени работают команды только из одного потока. Просто происходит переключение между потоками на уровне ОС. Так?
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Вопрос разработчикам: верно ли, что в QUIK, как таковой, многопоточности нет?
В QUIK есть многопоточность
Цитата
Старатель написал: Да, есть два потока: основной и main. Но в каждый момент времени работают команды только из одного потока. Просто происходит переключение между потоками на уровне ОС.
так обрабатывается ситуация при одновременном доступе к одному ресурсу
Дополнение к выше приведенному ответу. QUIK не управляет потоками. Ими управляет ОС. Но в реализации QLua есть отличие от "чистого" Lua, состоящее в том,что виртуальная машина QLua реализует собственное, потокобезопасное управление автоматической памятью QLua (запрос памяти под объекты QLua, возврат памяти, сборка мусора). Это правильно, и обусловлено тем, что все служебные функции обратного вызова QLua запускаются в потоке отличном от пользовательского (с именем main), но в среде (памяти) пользователя. Тут возникает только один вопрос: насколько эффективно в QLua реализовано это управление автоматической памятью? Но главным является то, что до версии QUIK 8.5, похоже это было реализовано достаточно корректно.Начиная же с версии QUIK 8.5 (а это переход c Lua 5.1 на 5.3, в котором существенно изменилось управление автоматической памятью) и вплоть до версии 8.8.0.55 при запусках моего теста управления автоматической памятью QLua в произвольные моменты времени возникают дампы ( все они пересланы мной в поддержку ARQU). Пока в версии >= 8.5 не будет реализовано корректное (пусть и не самое эффективное) потокобезопастное управление автоматической памятью версий QLua >= 8.5, QUIK будет нестабильным (надеюсь что разработчики QUIK это понимают).
local abs = math.abs
local function f()
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
return os.clock() - t
end
function main()
message(string.format('Расчёт в одном потоке: %0.1f', f()))
run = true
while run do
if param then
message(string.format('Расчёт в двух потоках [main]: %0.1f', f()))
param = nil
else sleep(1) end
end
end
function OnParam(class_code, sec_code)
if not run then return end
param = true
message(string.format('Расчёт в двух потоках [OnParam]: %0.1f', f()))
run = nil
end
Результат:
Цитата
Расчёт в одном потоке: 7.5 Расчёт в двух потоках [OnParam]: 32.2 Расчёт в двух потоках [main]: 31.9
Выводы делайте сами.
Надо делать так, как надо. А как не надо - делать не надо.
Добавим блокировку для "монопольного" вычисления в колбеке:
Код
local abs = math.abs
local function f()
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
return os.clock() - t
end
function main()
message(string.format('Расчёт в одном потоке: %0.1f', f()))
run = true
while run do
if param then
message(string.format('Расчёт в двух потоках [main]: %0.1f', f()))
param = nil
else sleep(1) end
end
end
function OnParam(class_code, sec_code)
if not run then return end
param = true
local t
table.ssort({0, 0}, function()
t = f()
return true
end)
message(string.format('Расчёт в двух потоках [OnParam]: %0.1f', t))
run = nil
end
Результат:
Цитата
Расчёт в одном потоке: 7.4 Расчёт в двух потоках [OnParam]: 6.7 Расчёт в двух потоках [main]: 7.3
Т.ч. вреда от main больше, чем пользы. И, если уж угораздило переносить расчёты в main, то то, что осталось в колбеках, лучше делать под блокировкой, чтобы main ни в коем случае не делал вычислений одновременно с колбеками. Последовательная работа потоков положительно скажется на общей производительности.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: вреда от main больше, чем пользы.
Это логичное следствие устройства самого луа, смотрим например в сорцы одной из функций, видим лок в начале и анлок в конце. Если функции вызываются параллельно из двух потоков, а это неизбежно при их параллельной работе, это будет приводить к переключению контекста между мейном и основным потоком квика на каждой итерации цикла. Отсюда накладные расходы и отсюда выгода от блокировки, захват критической секции в начале функции становится рекурсивным и не приводит к переключению контекста. Трудно придумать, как арка могла бы это изменить в текущей архитектуре с отдельным мейном. Только если отдать всю синхронизацию скриптописцу, что закончится известно как.
Хотя есть от main и польза: перенос сложных расчётов в main при одновременной работе двух и более таких скриптов (при достаточном количестве процессоров и условии, что колбеки не будут мешать расчётам).
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: Делать лок перед началом колбека и анлок по окончании, не?
Это и без арки можно сделать тем же ssort'ом, когда нужно. Всем и всегда - не нужно. Простой пример: в колбеке вызываете функцию из своей длл, она без лока выполняется. Если квик лок захватит, будет выполняться под локом. Нужен ли ей лок? Скорее всего нет, там в основном нативный код, в начале из стека выдрали аргументы, в конце засунули результат, чего бы мейну параллельно не поработать.