LINUX.ORG.RU

Сгенерить и скомпилить кусок C++ кода в рантайме. Какие есть фреймворки?

 


2

5

Я слышал, llvm юзают в какой-то СУБД для омтимизации запросов - запрос компилится в бинарный код и т.п.

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

if(type[i] == INT) deserializeInt();
else if ( type[i] == STRING ) deserializeString();

а хочется скомпилить по конфигу такой код:

deserializeInt();
deserializeInt();
deserializeString();
deserializeString();
deserializeInt();
deserializeInt();

Не буду скорее всего я ничего такого сейчас делать, просто интересно насколько это дико. Щас времена такие, что многое дикое становится недиким...



Последнее исправление: tailgunner (всего исправлений: 3)

"...мать, мать, мать" — привычно отозвалось эхо

anonymous
()

насчёт генерации не скажу, а для компиляции в рантайме фреймворк называется GCC :)

точнее, g++ -x c++ -

Harald ★★★★★
()

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

KivApple ★★★★★
()

Можно luajit встроить. И генерить код для него. Так ИМХО понадежнее получается

vromanov ★★
()

Зачем именно в рантайме генерировать? Используй protobuf.

invy ★★★★★
()
Ответ на: комментарий от anonymous

Тот чувак вроде из МС, да ещё индус до кучи.

anonymous
()

Я бы, как и товарищ выше, посоветовал не плюхаться сразу на рантайм, а использовать Protobuf. У него достаточно вменяемый IDL, привязки к куче языков.

Или дело совсем плохо, и до рантайма структура данных тебе совсем неизвестна?

// Вчитался внимательно...

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

То есть прямо так и есть, сначала в потоке приходит описание данных, а потом сами данные, и априорной информации по структуре нет?

Как-то это скайнетом попахивает... :)

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)

можно написать модуль десериализации для какого-нить скриптового языка и генерировать в рантайме скриптец под нужую структуру

anonymous
()

А в с++ уже нельзя что-ли сделать массив указателей на функции?

Типа


int (**sch)(int socket, void *data);

int init_sch(type_t *type, int sch_num_fields)
{
  sch = malloc( sch_num_fields * sizeof(void*));
  if( !sch ) return -1;

  // заполняем твою последовательность полей. Лучше конечно в цикле 
  // в соответствии с type[i]
  sch[0] = deserializeInt;
  sch[1] = deserializeInt;
  sch[2] = deserializeString();
  sch[3] = deserializeString();
  sch[4] = deserializeInt();
  sch[5] = deserializeInt();
  return 0;
}
...


// где-то потом, где надо десериализовать твой поток, вне зависимости от схемы просто делаешь:

for( i = 0; i < sch_num_fields; i++ ) sch[i](socket, data);

По скорости ничуть не медленнее будет, и без портянок с if( type == ... )

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 2)
Ответ на: комментарий от Stanson

По скорости ничуть не медленнее будет

Не медленнее, чем портянка if'ов. Но вот как в сравнении со специализированным кодом? Предсказание неявных переходов только в современных процессорах стало не самым глупым, а раньше просто запоминало и использовало предыдущий адрес перехода. Задержки на ошибку — 10-20 циклов.

Может оказаться быстрее спекулятивно распарсить, а потом cmov'ом взять значение. Ну а специально сгенерированный под ситуацию код может оказаться ещё быстрее.

Только вот смысл всего этого?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Может ему как раз портянка if'ов не нравится. А case он ненавидит. Ну вот вариант без портянок.

Ясен пень, специализированный код быстрее всего будет, однако ненамного.

Stanson ★★★★★
()
Ответ на: комментарий от AlexVR

Можно посмотреть в сторону ROOT от CERN

Какой-то огромный зверь, отличающийся нестандартными флагами в autotools (видел на мониторе коллеги)

UVV ★★★★★
()
Ответ на: комментарий от anonymous

microarchitecture

Как раз в эту самую pdf'ку смотрел, когда возник вопрос «а как долго выполняются неявные переходы».

Больше всего меня в этой pdf'ке удивило упоминание Skylake — автор всё ещё обновляет свой труд. В прошлом варианте, что я видел, об этом ни слова не было.

i-rinat ★★★★★
()
Ответ на: комментарий от Stanson

Во, с указателями на функции совет неплохой. Зачёт!

hlamotron
() автор топика
Ответ на: комментарий от AlexVR

не на сам РУТ, а на Ц++ интерпретатор(ы) - cling, cint последний предпочтительней, потому что может работать под виндой и для не завороченного Ц++ подходит вполне.

Valeriy_Onuchin ★★
()

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

А если надо сложную логику, то лучше используй скриптоту с jit, luajit например

annulen ★★★★★
()
Ответ на: комментарий от hlamotron

с помощью LLVM MC

лучше даже взять MacroAssembler из вебкита, он вообще никаких зависимостей не потянет, правда он поддерживает меньше архитектур

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.