создание исходного кода в процессе работы программы
От:
Аноним
Дата:
26.12.11 15:55
Оценка:
Здравствуйте! У меня такая вот дилемма.
Нужно писать программу (типа нейронной сети) которая состоит из маленьких модулей.
Причем. Состав и очередность модулей может быть разная.
1. Например если я заранее знаю какие модули и как будут вычислять я напишу так.
void MyFunction(double &INOUT_A, double &IN_B, double &OUT_E)
{
/// Входные данные А - Б.
///======= 1 модуль =======double С = А + Б
///======= 2 модуль =======double D = C * A
///======= 3 модуль =======
E = (D * B) ^ 2
/// Выходные данные А - E
}
Скомпилирую этот код. И естественно он будет выполняться молниеносно (количество модулей может быть очень большим).
2. Теперь мне нужно чтобы в процессе работы уже скомпилированной программы. Она (программа) читала файл и определяла количество и порядок модулей. для расчета и вычисляла его.
Я собираюсь решать это с помощью классов.
Имеем базовый class NODE с виртуальной функцие calc()
От базового класса создаем набор модулей.
Теперь код будет выполняться следующим образом:
А) Создание массива ссылок базового класса NODE.
B) Заполнение его нужными элементами.
C) Связывание (линкование) входных и выходных данных в дочерних классах.
D) Циклический обход массива:
while(....)
{
Node[i]->Calc();
}
Вроде все нормально будет работать.
Но
2.1. Выполняться этот обход массива будет много много раз.
2.2. Нужно как можно большее быстродействие.
3. Вопросы:
Можно ли как то создавать исходный код в процессе работы программы.
То есть. Я вижу это так.
3.1 Необходимо выделить необходимый объем памяти в программе.
3.2 Заполнение его кодом.
3.3 Получение ссылки на входные регистры, выходные регистры, и на основную функцию запуска расчета.
3.4 запускать эту функцию и наслаждаться таким же быстродействием как и в 1-ом примере.
4.
4.1 Скажите пожалуйста ссылки где такое могло быть реализовано.
4.2 Без Ассемблера это не реализовать?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте! У меня такая вот дилемма. А>Нужно писать программу (типа нейронной сети) которая состоит из маленьких модулей. А>Причем. Состав и очередность модулей может быть разная.
5. Может быть есть какой нибудь компилятор под Intel в виде одного EXE файла или комплекта не требующего установки?
5.1 То есть моя программа будет создавать файл с кодом .cpp
( в нем только функция или желательно класс , плюсы, минусы, деления, умножения, степени, корни )
5.2 Моя программа будет запускать Компилятор, который Будет компилировать этот файл в DLL.
5.3 Моя программа будет загружать эту DLL.
5.4 Наслаждаемся быстродействием и никакого Ассемблера
Re: создание исходного кода в процессе работы программы
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте! У меня такая вот дилемма. А>Нужно писать программу (типа нейронной сети) которая состоит из маленьких модулей. А>Причем. Состав и очередность модулей может быть разная.
А>1. Например если я заранее знаю какие модули и как будут вычислять я напишу так. А>
А>void MyFunction(double &INOUT_A, double &IN_B, double &OUT_E)
А>{
А> /// Входные данные А - Б.
А> ///======= 1 модуль =======
А> double С = А + Б
А> ///======= 2 модуль =======
А> double D = C * A
А> ///======= 3 модуль =======
А> E = (D * B) ^ 2
А> /// Выходные данные А - E
А>}
А>
А>Скомпилирую этот код. И естественно он будет выполняться молниеносно (количество модулей может быть очень большим).
Здравствуйте, RLX, Вы писали:
RLX>Здравствуйте, Аноним, Вы писали:
А>3. Вопросы: А>Можно ли как то создавать исходный код в процессе работы программы.
А>То есть. Я вижу это так. А>3.1 Необходимо выделить необходимый объем памяти в программе. А>3.2 Заполнение его кодом. А>3.3 Получение ссылки на входные регистры, выходные регистры, и на основную функцию запуска расчета. А>3.4 запускать эту функцию и наслаждаться таким же быстродействием как и в 1-ом примере.
Да, так делать можно.
А>4. А>4.1 Скажите пожалуйста ссылки где такое могло быть реализовано.
В LLVM, например: http://llvm.org/docs/tutorial/LangImpl4.html#jit — собственно, можно весь учебник прочитать, там как раз учебный язык с математикой делается.
А>4.2 Без Ассемблера это не реализовать?
Если делать вручную, то нет. Со сторонними компиляторами же вполне возможно.
RLX>5. Может быть есть какой нибудь компилятор под Intel в виде одного EXE файла или комплекта не требующего установки?
[url=http://bellard.org/tcc/]tcc[url].
RLX>5.1 То есть моя программа будет создавать файл с кодом .cpp RLX>( в нем только функция или желательно класс , плюсы, минусы, деления, умножения, степени, корни ) RLX>5.2 Моя программа будет запускать Компилятор, который Будет компилировать этот файл в DLL. RLX>5.3 Моя программа будет загружать эту DLL. RLX>5.4 Наслаждаемся быстродействием и никакого Ассемблера
Да, это самый простой способ. И вполне рабочий.
Re[2]: создание исходного кода в процессе работы программы
S>будет выполняться не сильно медленнее. Зато не нужно ничего генерировать налету для того что бы его сконфигурировать и выполнить.
Спасибо за предложение.
Вот именно так я и собираюсь делать.
Но мне почему то кажется что вызов функций обходится дороже.
Re[3]: создание исходного кода в процессе работы программы
Здравствуйте, RLX, Вы писали:
RLX>Здравствуйте, samius, Вы писали:
S>>Как я понимаю, код типа S>>
S>>struct MyFunction : public AbstractFunction
S>>
S>>будет выполняться не сильно медленнее. Зато не нужно ничего генерировать налету для того что бы его сконфигурировать и выполнить. RLX>Спасибо за предложение. RLX>Вот именно так я и собираюсь делать. RLX>Но мне почему то кажется что вызов функций обходится дороже.
Мерить надо.
Re[4]: создание исходного кода в процессе работы программы
Здравствуйте, RLX, Вы писали: RLX>Спасибо за ссылки.
Надеюсь, что ты читаешь документацию, но всё же замечу, что по второй ссылке в архиве с исходным кодом есть интересный пример libtcc_test.c. В этом примере показано как преобразовать исходный текст на языке C в пригодную для вызова функцию без всяких временных файлов — думаю, что это должно полностью ответить на твой исходный вопрос.
Re[4]: создание исходного кода в процессе работы программы
Здравствуйте, samius, Вы писали:
RLX>>Но мне почему то кажется что вызов функций обходится дороже. S>Мерить надо.
Мое мнение насчет того что функция обходится дороже основано на следующем.
Например имеем
1. ый вариант. Заранее скомпилированный код.
MyFunc()
{
A = B+C
D = A+B
G = D-C
И еще порядка 1000-100000 математических операций.
}
Рассмотрим один вызов
А = B+C
Тут:
1. Переменная А = В + С
2.-ой вариант. Через классы и "линковку" переменных заранее.
MyFunc()
{
Node[0].Do();
Node[1].Do();
Node[2].Do();
Node[3].Do();
И еще куча Do();
}
Рассмотрим один вариант.
Node[0].Do();
Тут.
1. Вызов функции Do();
2. Переменная А = В + С
(ни каких поместить переменную Б
поместить переменную С
вернуть переменную А
т.к. переменные заранее линкованы. Т.е функция-член класса без параметров)
То есть в последнем случае. Кроме вычисления регистров, есть еще вызов функции (без параметров).
Так Вот: вызов функции (без параметров), интересно, во сколько тактов обходится по сравнение со сложением.
Может быть кто знает?
Re[5]: создание исходного кода в процессе работы программы
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, RLX, Вы писали: RLX>>Спасибо за ссылки. WM>Надеюсь, что ты читаешь документацию, но всё же замечу, что по второй ссылке в архиве с исходным кодом есть интересный пример libtcc_test.c. В этом примере показано как преобразовать исходный текст на языке C в пригодную для вызова функцию без всяких временных файлов — думаю, что это должно полностью ответить на твой исходный вопрос.
Спасибо за наводку.
Я скорее выберу именно этот путь (в смысле пост-компоновку), хотя он, скорее всего, будет тернист, но мне нужно быстродействие.
Спасибо всем еще раз.
Re[3]: создание исходного кода в процессе работы программы
Здравствуйте, RLX, Вы писали:
RLX>Здравствуйте, samius, Вы писали:
RLX>>>Но мне почему то кажется что вызов функций обходится дороже. S>>Мерить надо.
RLX>Мое мнение насчет того что функция обходится дороже основано на следующем.
RLX>То есть в последнем случае. Кроме вычисления регистров, есть еще вызов функции (без параметров). RLX>Так Вот: вызов функции (без параметров), интересно, во сколько тактов обходится по сравнение со сложением.
Если ты это делаешь через виртуальные методы, то как минимум один параметр у тебя всегда присутствует — указатель на экземпляр класса. Просто в языке С++ его не нужно писать явно, но это не означает, что он куда-то исчезает из машинного кода. Но в любом случае передача одного параметра — это не очень дорого, если он передаётся в регистре, то считай что вообще бесплатно. А проблема тут даже не в самом вызове, а в том, что при использовании виртуальных функций этот вызов происходит по указателю, выбираемому из таблицы виртуальных функций, что может при некотором стечении обстоятельств довольно хорошо сбивать работу блока предсказания переходов процессора.
Но тут нужно понимать, что чем меньше размер твоей функции или блока, тем больше будет будут накладные расходы. Если твой типичный модуль считает нечто большое, например преобразование Фурье, то можно ни о чём не задумываться. Если же типичный модуль состоит из единственной операции типа "c = a + b", то накладные расходы тут могут стать заметными.
Например, как-то в процессе решения этой задачи я сравнил скорость кода, основанного на виртуальных функциях, со скорость кода, который переводил сначала программу в машинные коды, а затем исполнял её. Так как здесь типичная операция выглядела именно как "c = a + b" (то есть была довольно короткой), то скорость выполнения различалась где-то в 20 раз.
RLX>Может быть кто знает?
Это всё очень сильно зависит от контекста программы, процессора. Проще сделать замер для конкретного случая.
То есть, время инструкций в тактах конечно же известно. Но тут ещё играет роль время выборки адреса из памяти, вызванная этим зависимость по данным, сбои предсказания переходов, сброс конвеера процессора и тому подобное. Такое нужно оценивать профайлером, либо очень глубоко разбираться в деталях работы интересующей модели процессора.
Re[2]: создание исходного кода в процессе работы программы
Я скачал файлы и исходники с сайта http://bellard.org/tcc/
Но не как не могу понять что делать.
У меня установлена Visual Studio 2005.
Создал пустой проект dll: libtcc.
Закинул в папку с проектом все исходники.
Настройками играюсь играюсь , но чтот не получается собрать dll:
--- Юникод отключил
--- Прекомпилированные заголовки отключил.
--- Compile as: Compile as C Code (/TC). установил.
Там нужен файл "config.h", но его нет в исходниках.
Я, так понял, его сам должен создать, но что в нем должно быть, ума не приложу.
Я просто закоменитровал эту строку.
Все равно выскакивает куча ошибок.
ПРимерно такие
\i386-gen.c(97) : warning C4018: '>' : signed/unsigned mismatch
\tccpp.c(1873) : warning C4244: '=' : conversion from 'unsigned __int64' to 'unsigned int', possible loss of data
\tccelf.c(1210) : warning C4047: 'function' : 'const char *' differs in levels of indirection from 'int'
\tccelf.c(1210) : error C2065: 'CONFIG_SYSROOT' : undeclared identifier
Помогите. Может у кого есть уже скомпилированный libtcc.dll libtcc.lib ?
Спасибо watch-maker за наводку на libtcc_test.
Это то что нужно.
Я скачал файлы и исходники с сайта http://bellard.org/tcc/
Но не как не могу понять что делать.
У меня установлена Visual Studio 2005.
Создал пустой проект dll: libtcc.
Закинул в папку с проектом все исходники.
Настройками играюсь играюсь , но чтот не получается собрать dll:
--- Юникод отключил
--- Прекомпилированные заголовки отключил.
--- Compile as: Compile as C Code (/TC). установил.
Там нужен файл "config.h", но его нет в исходниках.
Я, так понял, его сам должен создать, но что в нем должно быть, ума не приложу.
Я просто закоменитровал эту строку.
Все равно выскакивает куча ошибок.
ПРимерно такие
\i386-gen.c(97) : warning C4018: '>' : signed/unsigned mismatch
\tccpp.c(1873) : warning C4244: '=' : conversion from 'unsigned __int64' to 'unsigned int', possible loss of data
\tccelf.c(1210) : warning C4047: 'function' : 'const char *' differs in levels of indirection from 'int'
\tccelf.c(1210) : error C2065: 'CONFIG_SYSROOT' : undeclared identifier
Помогите. Может у кого есть уже скомпилированный libtcc.dll libtcc.lib ?
PS// Или (я так понял) нужно какой то GNU компилятор.??
Re[4]: создание исходного кода в процессе работы программы
Я делал такое. Нужно было написать что-то вроде Delphy для портативного устройства. В общем берете mingv и компилете все им на лету, а потом запускаете в отдельном процессе полученный код.
Но это неверное решение. Лучше научить иераршиу классов правильно десериализовываться на основе config-файлов (можете создать свой маленький DSL-язык и парсите его lex/yacc), потом создавать динамическую структуру и вперед.
Re[2]: создание исходного кода в процессе работы программы
RLX>5. Может быть есть какой нибудь компилятор под Intel в виде одного EXE файла или комплекта не требующего установки?
Такой компилятор есть, только это компилятор с паскаля, в комплекте с дельфи. Товарищ так и делал лет 10 назад (была задача протабулировать любую функцию): из с++ программы генерил исходник длл на паскале, запускал в скрытом режиме на компиляцию, а потом поднимал длл и вызывал оттуда функцию. По моему паскаль лучше чем лисп.