Сижу туплю, не пойму как мне профилировать dll на Си++ с помощью Visual Studio 2017. dll вызывается из Луа Что писать в Command-line arguments и Working directory? При попытке запустить профилирование появляется ошибка: Это сопровождается текстом: Profiling started. Instrumenting D:\_c++\runfast\Release\runfast.dll in place Info VSP3049: Small functions will be excluded from instrumentation. Microsoft ® VSInstr Post-Link Instrumentation 15.8.18219.1 x86 Unable to obtain debug information. Link with the /PROFILE linker switch. PRF0002: Instrumentation failed with these options: /u "D:\_c++\runfast\Release\runfast.dll" /excludesmallfuncs. Please check the output window for additional details. Data written to D:\_c++\runfast\info181001(3).vsp. Profiling finished. Profiling complete.
Английские слова все понятны, но технический смысл я не улавливаю. Помогите пожалуйста
2) поместить все искомые модули в папки /lua (*.lua) и /Include (*.dll -- ещё можно в корень Quik'а кидать их, а для некоторых .dll не можно, а нужно) в дистрибутиве Quik.
а я имею право это делать для модулей устанавливаемых с помощью LuaRocks? Там какой-то сложный процесс идёт при установке. Неужели просто можно взять и перекопировать в /lua? Выглядят эти модули странно: -- И вытекающий вопрос. я не хочу ставить на виртуалку VisualStudio, чтобы вызывать Developer Command Prompt. Я могу установить пакет на ноутбук (на ноутбуке визуал студия стоит), а потом перекопировать на виртуалку установленный пакет?
Второй вопрос. LuaRocks позиционируется как удобная штука, чтобы модули можно было вызывать с помощью require Пишу require "chronos" и он его не находит :(
справедливости ради надо сказать, что ни в одной из этих папок действительно нет этого модуля. Как же мне его подключить?
s_mike@rambler.ru написал: Ну да, типа такого. Можно ещё посмотреть на возвращаемое значение pcall
хм... а как мне в функцию foo передать параметр?
Код
function main()
while is_run do
pcall(foo("privet"))
mm(t)--печать в виде message таблицы из файла.
sleep(1000)
end
end
function foo(slovo)
a=slovo
dofile ("C:\\1.lua")--здесь сидит таблица t
end
выдаёт ошибку bad argument #1 to 'pcall' (value expected)
ооо, спасибо! который раз уже спасаете :) Вроде бы получилось, и не выбивает если в файле написать кривулины Вы это имели в виду или можно понадёжнее сделать?
Код
function main()
while is_run do
pcall(foo)
mm(t)--печать в виде message таблицы из файла.
sleep(1000)
end
end
function foo()
dofile ("C:\\1.lua")--здесь сидит таблица t
end
Но иногда в этом файле могут быть кривые данные. Если вызывать этот файл с помощью dofile (tbl.lua), могут быть ошибки и основной скрипт остановится с ошибкой. Как написать в духе:
dofile (tbl.lua), но если там нечитаемый бред, то идти дальше и не обновлять таблицу t (пользоваться старой).
#include <iostream>#include <map>
#include <string>
int main ()
{
std::map<std::string, int> period_muvinga;
period_muvinga["GAZP"] = 23;
period_muvinga["SBER"] = 19;
period_muvinga["GMKN"] = 20;
// Iterate over all the key,value pairs in map
//
for (const auto & p: period_muvinga)
{
// Extract key from pair
std::string ticker = p.first;
// Extract value from pair
int period = p.second;
std::cout << ticker << " = " << period << std::endl;
}
return 0;
}
Для других целей - более сложных - мне остаётся не понятным в какой части dll объявлять этот массив. Замысел вкратце. Объявить массив map с названием average_bid. Вопрос где это делать? Ключи массива - тикеры акций. объявляются вместе с массивом. Значения массива - векторы, накапливающие биды за 100 колбеков OnQuote. Это я умею. Цель - посчитать среднее арифметическое бидов за 100 приходов колбека. --- Использовать OnInit пока не хочу, потому что у меня в нём и так уже в Луа 50 строчек кода, объявляющих таблицы и переменные.
Антон, с этим я уже разобрался, и в первую очередь благодаря Вам ;) Но я имел в виду другое. Уже внутри кода dll мне придётся работать с тем, что в Луа мне знакомо как таблицы. У меня 55 инструментов. Я хочу посчитать по ним средний бид за 100 итераций (за 100 колебаний стакана). Принимать этот бид в dll я уже могу. Но теперь мне надо где-то накапливать данные по каждой бумаге. В Луа я бы это делал в таблицах типа: average_bid[sec] А в Си++ где их хранить?
Прошу подсказать какой аналог глобальной таблицы Луа для Си++ Совсем точноЙ формулировкой вопроса будет, как то же самое написать на Си++
Код
ticker_list="GAZP,SBER,GMKN"
period_muvinga={}
period_muvinga.GAZP=23
period_muvinga.SBER=19
period_muvinga.GMKN=20
for sec in string.gmatch(ticker_list,"%a+") do
local period=period_muvinga[sec]
end
и второй вопрос. Когда дойдёт дело до объявления чего-то глобального в Си++ (то что является ответом на первый вопрос), в какой части кода это объявлять? Я пока не могу придумать ничего лучше кроме как здесь. Речь идёт про dll, написанную на Си++:
А этот цикл обрывается на второй итерации:
for (int i = 1; i<=4; i++){
printf("%i", i);
printf("\n");
lua_rawgeti(L, -2, i);
lua_getfield(L, -1, "quantity");
auto q = lua_tonumber(L, -1);
}
Пишет 1 2
Путём опытов я понял, что проблема в функции lua_rawgeti(L, -2, i); Она обрывает цикл на второй итерации. Почему? П.С. Если это важно, то всё это происходит внутри обработки колбека OnQuote
Антон, спасибо!!! К тому моменту как увидел ваш ответ, уже накорябал свой вариант, но по прежнему не знал как читать вложенные таблицы (стакан и его поля).
Код
static int forLua_OnQuoteC(lua_State* L) {
lua_pushnil(L);
int s = 0;
while (lua_next(L, -2))
{
s = s + 1;
const char* key = lua_tostring(L, -2);
double val = lua_tonumber(L, -1);
lua_pop(L, 1);
}
return 1;
}
и ещё вопрос. Я понял суть врапперов, естественно с ними проще. но всё же, как решить мою задачу без них? принять таблицу-стакан из OnQuote внутри dll? я сейчас читаю книгу по Луа, написанную её разработчиком. Иду шаг за шагом по главе "C API". В голове каша, но первые проблески уже есть. Строки и числа я уже спокойно обрабатываю в dll.
Спасибо этому форуму за советы и подсказки. Как принять в dll таблицу с целочисленными ключами, разобрался. Прошу подсказать как внутри dll разобрать по полям более сложную таблицу.
Код
qt=getQuoteLevel2(class, sec)
Согласно документации она возвращает таблицу, в которой два стринга и две вложенных таблицы. Мне нужны для работы все четыре. Как мне, к примеру, получить объём из 3-й котировки на покупку?
Для разбора таблицы с целочисленными индексами мой код внутри dll выглядит так:
Код
static int forLua_SumArray(lua_State* L) {
// Get the length of the table (same as # operator in Lua)
int n = lua_objlen(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
Michael Bulychev, тогда мне совсем ничего не понятно. Почему тогда Иерусалимскис пишет в своей книге по Луа: то есть стек локальный. Зачем тогда lua_newthread()?
Алексей Ч, в предложенном вами варианте Луа равна по скорости dll на Си
Код
function sum_new(t)--функция Алексея Ч.
local sum = 0
for x=1, #t do
sum = sum + t[x]
end
return sum
end
iterations=1000000
function main ()
t={}
for i=1,20 do
table.insert(t,i)
end
start=os.clock()
for i=1,iterations do
s=runfast.SumArray(t)--функция из dll
end
finish_dll=os.clock()-start
mm("dll:"..finish_dll)
start=os.clock()
for i=1,iterations do
s=sum(t)--старая функция на Луа с for... pairs
end
finish_lua=os.clock()-start
mm("Lua:"..finish_lua)
start=os.clock()
for i=1,iterations do
s=sum_new(t)--новая функция без pairs
end
finish_lua_new=os.clock()-start
mm("Lua new:"..finish_lua_new)
mm("Lua old slower:"..math_round((finish_lua/finish_dll),1))
mm("Lua new slower:"..math_round((finish_lua_new/finish_dll),1))
end
Алексей Ч, спасибо. Я не знал, что предложенный вами вариант будет быстрее. Обязательно начну использовать. --- Но ваш комментарий о другом. Я про другое спросил. Почему dll не даёт преимущества в скорости на больших таблицах? Почему при обсчёте таблицы с 20 полями и таблицы с 40 полями разница в производительности одинаковая?
Вот функция на Си++ внутри dll. Она принимает таблицу и выдаёт обратно в Луа сумму элементов этой таблицы.
Код
static int forLua_SumArray(lua_State* L) {
// Get the length of the table (same as # operator in Lua)
int n = lua_objlen(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
Я ожидаю, что чем больше элементов будет в таблице, тем сильнее dll должна опережать аналогичные подсчёты в Луа. Написал код для сравнения скорости.
Код
iterations=1000000
function main ()
t={}
for i=1,20 do--вставляем в таблицу 20 элементов
table.insert(t,i)
end
--гоняем цикл миллион раз
start=os.clock()
for i=1,iterations do
s=runfast.SumArray(t)
end
finish_dll=os.clock()-start
mm("dll:"..finish_dll)
--гоняем цикл миллион раз
start=os.clock()
for i=1,iterations do
s=sum(t)
end
finish_lua=os.clock()-start
mm("Lua:"..finish_lua)
mm("Lua slower:"..math_round((finish_lua/finish_dll),1))
end
Луа медленнее в 2,4 раза. Я мучаюсь с Си ради роста скорости в 100 раз, ну да ладно. В 2,5 раза тоже кое-что. Сказываются транспортные издержки при перекидывании данных между Си и Луа. ************************ А теперь удивительное для меня. Заполняю таблицу 40 элементами.
Код
t={}
for i=1,40 do
table.insert(t,i)
end
Значит внутри Си++ будет производиться в 2 раза больше операций и она сможет лучше проявить своё преимущество в скорости по сравнению с Луа. Но нет: при 40 элементах в таблице преимущество Си в скорости такое же.
Почему? Я думал, что чем больше таблица, тем быстрее будет работать вариант кода с dll. Объясните пожалуйста.
вообще-то это прикольно. Вы написали пример из разряда "как не надо писать программы" В вашем примере операция сложения занимает промерно 1% всего времени
static int forLua_SumArray (lua_State* L) { // Get the length of the table (same as # operator in Lua)
int n = luaL_len(L, 1);
double sum = 0.0;
// For each index from 1 to n, get the table value as a number and add to sum
for (int i = 1; i <= n; ++i) {
lua_rawgeti(L, 1, i);
sum += lua_tonumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, sum);
return 1;
}
всё хорошо, но в Луа 5.1. нет функции luaL_len. Она появилась в более поздних версиях. Вот код этой функции в Луа 5.3.
Как мне это внедрить в свою dll? Как дописать строку в lauxlib.h - это понятно. А вот файла lauxlib.c в моей Луа 5.1.5 вообще нет.
Алексей Ч, спасибо. я нашёл функцию, которая это делают
Код
function time_to_number(t) return (math.floor(t / 10000) * 60 * 60) + ((math.floor(t / 100) % 100) * 60) + (t % 100)
-- you can also use % 10000 if the hours are limited to two digits
end
А если надо подобное число конвертировать обратно, то есть другая функция.
Код
function time_split(t)
local hour = math.floor(t / 3600)
local min = math.floor((t % 3600) / 60)
local sec = (t % 3600) % 60
return hour, min, sec
end
Ответы не понятны. При чём здесь 1970 год? Я вытягиваю из текущей таблицы время последнего изменения через tonumber(getParamEx("SPBFUT",tech_instr,"CHANGETIME").param_value) оно имеет вид 101200 Добавлять секунды мне нужно к этому числу.
У меня в dll две функции. Обе постоянно что то делают со стеком. Есть ли риски того, что они будут по ошибке брать элементы друг друга? Или для каждой из них свой стек и путаница не грозит?
Спасибо за ответ, но этот вариант не подходит. При каждом срабатывании колбека скрипт будет обращаться к dll. Луа в КВИК встроена настолько кривобоко, что это получается долго. Луа:
Код
for i=1,10000000 do
r = i+i
end
Луа+dll на Си++
Код
for i=1,iterations do
r = runfast.AddTwoNumbers(i, i)
end
Второй код работает в 3,6 раза медленнее, чем первый из-за постоянного перекидывания данных из Луа в Си. Ваш вариант предусматривает те же самые задержки.
Мне нужно колбек OnQuote полностью упаковать внутрь dll. Вызвать его один раз, и потом он крутится только внутри dll
Как делать простые вещи с dll вроде разобрался. Прошу проконсультировать, как поместить в dll колбек OnQuote Чтобы это выглядело как то так: package.cpath = "C:\\runfast.dll" require "runfast" runfast.OnQuote() ... и так далее. Ума не приложу где мне эту строчку runfast.OnQuote() размещать. За пределами main как и сейчас? подскажите пожалуйста
Я совершаю в Луа арифметические операции со временем. Например 124500+5=124505 (12:45:05). По какой формуле я могу избежать проблемы с 60 минутами/секундами? 124459+5=124504 (не 124464) Как этого добиться?
Enfernuz, уже уткнулся. Всё это происходит, потому что мои колбеки OnQuote захлёбываются. Я принимаю 55 инструментов, и скрипт на луа не справляется. В каждом колбеке есть логика и математика, которую нельзя переместить в main. поэтому нужна скорость
Enfernuz, то есть мне для достижения максимальной скорости нужно в dll запихать всё, что сейчас находится в Луа-скрипте. Это позволит обратиться к dll единожды при вызове библиотеки. Вся логика робота будет в dll. А если переносить в dll только часть функций, то Луа по скорости победит C++, потому что долгое взаимодействие Луа с dll...
Написал функцию так, чтобы цикл крутился внутри dll:
Код
static int forLua_AddCircle(lua_State *L) {
double d1 = luaL_checknumber(L, 1); //с чего начинать цикл
double d2 = luaL_checknumber(L, 2); //количество итераций
double r;
double i;
for (i = d1; i <= d2; i++)
{
r = i + i;
}
return(1);
}
Код
package.cpath = "C:\\runfast.dll"
require("runfast")
iterations=100000000
function main()
start=os.clock()
for i=1,iterations do
r = runfast.AddTwoNumbers(i, i)
end
finish=os.clock()-start
message ("C dll:"..tostring(finish), 1)
start=os.clock()
for i=1,iterations do
r = i+i
end
finish=os.clock()-start
message ("Lua:"..tostring(finish), 1)
start=os.clock()
r = runfast.AddCircle(1,iterations)
finish=os.clock()-start
message ("C dll circle:"..tostring(finish), 1)
end