В среде 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 логических процессора.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 01.02.2015
17.10.2016 00:13:52
потому что в первом случае, виртуальная машина запускается отдельным потоком внутри процесса QUIK-а у которого и так полно потоков и поболее приоритетных чем твой скрипт и во втором случае - скрипт запускается в однопоточном процессе ("из командной строки" - это я так понимаю из интерпретатора LUA).
Кроме того, количество ядер - абсолютно никак не влияет на QUIK - бо как он, как уже писалось на форуме - не использует все преимущества многоядерности, а целиком полагается в распределении нагрузки на ОС.
Пользователь
Сообщений: Регистрация: 01.02.2015
17.10.2016 00:20:22
я уже приводил 3 примера:
чем больше на графиках наложено индикаторов - тем дольше выполняется скрипт (вне зависимости от того, что он мол де - находится "в майне")
чем больше открыто графиков и окон в квике - тем дольше выполняются скрипты. ЭТО ПОЗОРНЫЙ ФАКТ о котором так любят умалчивать так называемые "разработчики"
стОит поводить окном любой таблицы или графика в QUIK-е - скрипты - ожидаемо начинают притормаживать.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
17.10.2016 06:24:17
Правильный ответ в данном случае: Потому что в quik Lua собрана с поддерхкой многопоточности. Разница - это накладные расходы на синхронизацию доступа к хранилищу переменных (сделано в Lua надёжно, но не очень эффективно)
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
17.10.2016 11:38:46
Мда... Двухпоточность в QLua работает действительно неэффективно: Вот сейчас запустил одновременно три скрипта в QUIK. Общее время работы составило 12.9 сек, что больше, чем при последовательном их запуске через консоль (3.5+3.5+3.6=10.6 сек). Таким образом, выигрыша в производительности от многопоточной схемы работы в QUIK, действительно, не наблюдается. Единственный плюс - то, что интерфейс не зависает при работе длительных циклов в main.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 30.05.2016
17.10.2016 15:02:55
Цитата
тот самый написал: я уже приводил 3 примера: чем больше на графиках наложено индикаторов - тем дольше выполняется скрипт (вне зависимости от того, что он мол де - находится "в майне") чем больше открыто графиков и окон в квике - тем дольше выполняются скрипты. ЭТО ПОЗОРНЫЙ ФАКТ о котором так любят умалчивать так называемые "разработчики" стОит поводить окном любой таблицы или графика в QUIK-е - скрипты - ожидаемо начинают притормаживать.
Выходит что луа машина в квике крутится в потоке его gui? Но это же очень плохо как для самого квика так и для сриптов...
Выходит что луа машина в квике крутится в потоке его gui? Но это же очень плохо как для самого квика так и для сриптов...
так это явно написано в документации. Но есть поток main() - он не мешает основному потоку
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
17.10.2016 17:19:58
Цитата
Старатель написал: Мда... Двухпоточность в QLua работает действительно неэффективно:
это не понятно. Двухпоточность рабатает отлично. Поток main() не мешает основному потоку А время - понятные накладные расходы.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
17.10.2016 19:00:12
Цитата
swerg написал: Двухпоточность рабатает отлично. Поток main() не мешает основному потоку А время - понятные накладные расходы.
Разве что не мешает... Пока не задействуешь потокобезопасные функции QLua. Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно. А по факту в QUIK накладные расходы слишком высоки.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 01.02.2015
17.10.2016 20:32:56
Цитата
swerg написал: Но есть поток main() - он не мешает основному потоку
балабол
Пользователь
Сообщений: Регистрация: 01.02.2015
17.10.2016 20:35:20
Цитата
swerg написал: Двухпоточность рабатает отлично. Поток main() не мешает основному потоку
слышь ты...умник, ля... - да завали ты уже своё е..
можно, как и в майне тормоза квику создать, равно, как и можно сам квик - окнами и индикаторами перегрузить - и также будут тормоза в майне.
Пользователь
Сообщений: Регистрация: 01.02.2015
17.10.2016 20:43:21
Цитата
Старатель написал: Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно.
как только QUIK наконец начнёт импортировать функции вида: SetThreadAffinityMask
тогда и только тогда он хоть на чуточку приблизится к поддержке многоядерности.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
18.10.2016 06:14:33
Цитата
Старатель написал: Разве что не мешает... Пока не задействуешь потокобезопасные функции QLua. Но в моём понимании "отличная работа" многопоточного приложения - это когда на многоядерном ЦП несколько параллельно работающих задач выполняются быстрее, чем те же несколько задач, выполняемых последовательно.
вы как бы правы, но кто говорил про многопоточность? Ну и потом: запустите ваши скрипты отдельными скриптами в quik, и функции main будут работать паралллельно (кстати, надо попробовать)
Цитата
Старатель написал: А по факту в QUIK накладные расходы слишком высоки.
это откуда вывод про слишком? У вас есть другое приложение, на котором вы можете поставить аналогиный эксперимент?
swerg написал: Радует, что балуешь ты нас этим постоянно.
кого вас-то?...
всех,кто имеет удовольствие читать твою ахинею.
Запрос фактов забавно слышать от того, кто их не приводит
Пользователь
Сообщений: Регистрация: 01.02.2015
18.10.2016 20:45:25
Цитата
swerg написал: всех,кто имеет удовольствие читать твою ахинею.
а ты тут за всех, что ль уже взялся говорить, высерок?
Цитата
swerg написал: Запрос фактов забавно слышать от того, кто их не приводит
и мне тоже "забавно" слышать "излияния" от такого чмошника, как ты... Заикнулся про то, что есть полностью скаченный старый форум, а потом, как су ка последняя язык в ж пу засунул.... чмо ты и есть чмо
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
19.10.2016 05:02:43
В зерколо смтришься при написании. Это правильно.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
27.11.2016 23:29:52
Вопрос разработчикам: верно ли, что в QUIK, как таковой, многопоточности нет? Да, есть два потока: основной и main. Но в каждый момент времени работают команды только из одного потока. Просто происходит переключение между потоками на уровне ОС. Так?
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 23.01.2015
28.11.2016 11:37:45
Цитата
Старатель написал: Вопрос разработчикам: верно ли, что в 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 это понимают).
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 19:50:49
Немного модифицируем первоначальный скрипт:
Код
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
Выводы делайте сами.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 20:44:05
Добавим блокировку для "монопольного" вычисления в колбеке:
Код
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 ни в коем случае не делал вычислений одновременно с колбеками. Последовательная работа потоков положительно скажется на общей производительности.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 21.08.2015
26.07.2020 21:31:20
Цитата
Старатель написал: вреда от main больше, чем пользы.
Это логичное следствие устройства самого луа, смотрим например в сорцы , видим лок в начале и анлок в конце. Если функции вызываются параллельно из двух потоков, а это неизбежно при их параллельной работе, это будет приводить к переключению контекста между мейном и основным потоком квика на каждой итерации цикла. Отсюда накладные расходы и отсюда выгода от блокировки, захват критической секции в начале функции становится рекурсивным и не приводит к переключению контекста. Трудно придумать, как арка могла бы это изменить в текущей архитектуре с отдельным мейном. Только если отдать всю синхронизацию скриптописцу, что закончится известно как.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 23:55:10
Хотя есть от main и польза: перенос сложных расчётов в main при одновременной работе двух и более таких скриптов (при достаточном количестве процессоров и условии, что колбеки не будут мешать расчётам).
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
28.07.2020 14:55:12
Цитата
Anton написал: Трудно придумать, как арка могла бы это изменить в текущей архитектуре с отдельным мейном.
Делать лок перед началом колбека и анлок по окончании, не?
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 21.08.2015
31.07.2020 08:38:12
Цитата
Старатель написал: Делать лок перед началом колбека и анлок по окончании, не?
Это и без арки можно сделать тем же ssort'ом, когда нужно. Всем и всегда - не нужно. Простой пример: в колбеке вызываете функцию из своей длл, она без лока выполняется. Если квик лок захватит, будет выполняться под локом. Нужен ли ей лок? Скорее всего нет, там в основном нативный код, в начале из стека выдрали аргументы, в конце засунули результат, чего бы мейну параллельно не поработать.