LINUX.ORG.RU

Хочу C++ без C++

 ,


0

2

Такие дела.
Безплюсового старшего брата сразу отметаем. Интерпретируемые/JIT-языки тоже отметаем. Языки типа D, в которых размер бинарника хелловорда около мегабайта отметаем так же.
Хотелось бы, что-то типа Python, но который не требует интерпретатора, как Cython, для своей работы.
Что там остается? Есть ли Путь? Сколько времени прошло с создания C/C++, появилась ли им вменяемая альтернатива?
Если писать с нуля транслятор Python (СТ) в код на C (не машинный, не llvm), какие там основные проблемы будут? Преобразование грамматик? Падение производительности? В чем основные сложности и примерно сколько времени займет реализация такого проекта? Кто-нибудь подобным занимался?



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

Ответ на: комментарий от kirk_johnson

std::vector<B> data(1000); Это ручное управление памятью или нет? Какая куча ошибок появится, если я буду использовать такие конструкции вместе с RAII и ссылками? И какие ошибки бы тут предотвратил GC?

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

Проявляется не только в Java.

В .net можно вручную управлять памятью в отличии от жапки.

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

Потому что риалтайм писать нельзя.

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

Я тебе, наверное, сейчас раскрою страшную тайну: в hard realtime системах динамическая память не используется практически никогда. Да-да, потому что malloc ВНЕЗАПНО может выдавать произвольную задержку, поскольку ему тоже нужно найти свободный кусок памяти.

В случае же с soft realtime GC совершенно не мешает. Erlang, например, является типичным примером soft realtime системы, изначально разработанной для телекома.

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

в hard realtime системах динамическая память не используется практически никогда. Да-да, потому что malloc ВНЕЗАПНО может выдавать произвольную задержку

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

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

И какие ошибки бы тут предотвратил GC?

GC бы предотвратил, например, фрагментацию памяти, с которой сейчас в мире C++ борятся с помощью кастомных аллокаторов и хитрого колдунства. Firefox тому будет примером.

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

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

Круто. Запили. Что с фрагментацией делать, если я, например, захочу освободить память в середине стэка?

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

А что с памятью? Ну бери заводи вспомогательный стек, который бы отмечал интервалы памяти, освобожденны в стеке

стек1:
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789..
<данные><данные__данные__данные><данные> дальше пустота

стек со свободными интервалами:
<свободно 0x29 - 0xff>
освобождаем второй аллоцированный кусок на стеке
стек1:
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789..
<данные><свободно_свободно-----><данные> дальше пустота

стек со свободными интервалами
<свободно 0x29 - 0xff><свободо 0x08 - 0x1F>
Свободные интервалы можно через RLE кодирование делать

Иногда надо производить дефрагментацию такого стека Доступ к аллоцированным на таком стеке данным надо осуществлять не напрямую, а хранить смещения в массиве, и делать двойное разыменование. Таким образом, при дефрагментации стека нам не надо будет патчить все указатели на стек(знать места, где хранятся указатели на стек и патчить), а пропатчить можно будет только таблицу смещений относительно начала стека. Процедуру дефрагментации стека можно выполнять в фоновом режиме, и она может быть прервана в любой момент, так что реалтаймовости она не нарушает

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

Что делать со указателями на используемую память, которую я не собираюсь освобождать, но которую нужно перенести для дефрагментации? Как ты предлагаешь это в фоне делать?

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

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

В фоне - а в чем проблема собственно? По-моему нет никакой особой проблемы в том, чтобы это в фоне делать. Могу за деньги такое написать на Си

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

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

Ты предлагаешь ещё и таблицу всех указателей держать? А потом фризить выполнение кода, копировать память, править указатели и продолжать шоу? Ты только что изобрёл половину сборщика мусора. Очень криво изобрёл.

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

Я тебе, наверное, сейчас раскрою страшную тайну: в hard realtime системах динамическая память не используется практически никогда.

Кастомный аллокатор используется и динамическая память тоже.

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

Далеко не всегда. Очень часто с памятью работают просто как с большим массивом данных, который всегда доступен. Никаких malloc/free и т.п. Я сейчас о простейших контроллерах, если что.

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

А потом фризить выполнение кода

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

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

В фоне - а в чем проблема собственно?

Алсо да, как ты это в фоне будешь делать при условии наличия всего одного процессора? Через астрал что-ли?

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

Когда процессор не на 100% загружен реалтаймовыми задачами, которые прерывать нельзя ни в коем случае - буду делать.

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

1. memcpy - далеко не самая дешёвая вещь.

2. ты осознаёшь что описываешь работу копирующего GC, против которого так громко выступаешь?

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

Когда процессор не на 100% загружен реалтаймовыми задачами, которые прерывать нельзя ни в коем случае - буду делать.

Что значит «не на 100% загружен»? Процессор или занят или нет, у него нет других состояний. Соответственно, твоя хрень должна успеть сработать между двумя задачами реального времени.

P.S. Ты вообще в курсе, что существуют специальные сборщики мусора для систем реального времени?

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

1) Это не ошибка. (речь шла именно о том, какие именно ошибки предотвратит GC)
2) В жапке тоже heap fragmentation - проблема.

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

memcpy можно прервать в любой момент. От GC тут только дефрагментация. Выделять и освобождать надо все так же вручную

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

Что значит «не на 100% загружен»? Процессор или занят или нет, у него нет других состояний. Соответственно, твоя хрень должна успеть сработать между двумя задачами реального времени.

Ну и отлично, когда все реалтаймовые задачи выполнены за определенный отведенный квант времени, можно подефрагментировать.

P.S. Ты вообще в курсе, что существуют специальные сборщики мусора для систем реального времени?

Конечно, но они не особо эффективны

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

1) Это не ошибка. (речь шла именно о том, какие именно ошибки предотвратит GC)

Да, я знаю, хотел написать об этом в том комментарии, но не успел. Тем не менее, это очень хорошая причина использовать GC.

2) В жапке тоже heap fragmentation - проблема.

Намного меньшая, чем в C++. К тому же, Java делает плохую славу практически всему. Сравни с тем же Haskell, у которого один из лучших сборщиков мусора, и фрагментация практически не встречается как проблема, за исключением работы с pinned memory, но это как раз таки то самое ручное управление памятью, в которую GC не подпускают (ByteStrings, etc).

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

Все упомянутые языки(кроме Rust) обладают одним неприятным свойством - в них неотключаемый GC

Справедливости ради - в D/Nim GC отключается. Вопрос о том что останется от языка оставим за скобками.

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

memcpy можно прервать в любой момент.

Серьёзно? Ты предлагаешь «на половину» скопировать память, с которой ведётся работа? Я, кстати, так и не понял, как именно ты предлагаешь «в фоне» копировать активную память, с которой кто-то работает, и какой в этом вообще будет смысл.

Выделять и освобождать надо все так же вручную

И смысл этого? Просто чтобы показать свою крутость?

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

Серьёзно? Ты предлагаешь «на половину» скопировать память, с которой ведётся работа?

Да, наполовину скопировал, но я еще не поправил тот указатель на то место куда я наполовину скопировал память. И если меня экстренно прервали на копировании памяти, копирование просто останавливается, и работать можно дальше. А докопировать потом

И смысл этого? Просто чтобы показать свою крутость?

Смысл в том, что GC неэффективны

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

А докопировать потом

Что докопировать? Рабочий код может поменять уже скопированный тобой кусок памяти, что ты копировать собираешься-то? Вот у меня массив данных, для дефрагментации памяти его нужно передвинуть в начальную область. Твою мегадефрагментацию прервали на середине чтобы поменять часть элементов массива. Что ты после этого «докопировать» будешь? И как ты вообще будешь копировать, если, например, этот массив пересекается с той областью в которую ты его будешь копировать?

Смысл в том, что GC неэффективны

Почему?

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

Тем не менее, это очень хорошая причина использовать GC.

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

Сравни с тем же Haskell

Совершенно другой язык, с совершенно другой парадигмой, как их можно вообще сравнивать?

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

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

Проблема в том, что с большой вероятностью получится ублюдочный кривой говномонстр от SZT.

Совершенно другой язык, с совершенно другой парадигмой, как их можно вообще сравнивать?

Haskell компилируется в код для x86_64, C++ компилируется в код для x86_64, почему бы их не сравнить?

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

Что докопировать? Процесс может поменять уже скопированный тобой кусок памяти, что ты копировать собираешься-то? Вот у меня массив данных, для дефрагментации памяти его нужно передвинуть в начальную область. Твою мегадефрагментацию прервали на середине чтобы поменять часть элементов массива. Что ты после этого «докопировать» будешь?

Нет, не может. Я копируемый блок перед этим копированием предварительно пометил как залоченный. При любом обращении к нему, будет вызван особый обработчик, который обозначит что этот блок теперь уже НЕЛЬЗЯ докопировать, а можно только с нуля копировать, и тогда если опять начнется сборка мусора, будет копирование с самого начала. Или можно вообще всегда копирование с нуля начинать, если вдруг кто прервал на середине, если не хочется с этим голову морочить.

Почему?

Потому что дополнительные накладные расходы

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

Нет, не может. Я копируемый блок перед этим копированием предварительно пометил как залоченный. При любом обращении к нему, будет вызван особый обработчик, который обозначит что этот блок теперь уже НЕЛЬЗЯ докопировать, а можно только с нуля копировать, и тогда если опять начнется сборка мусора, будет копирование с самого начала. Или можно вообще всегда копирование с нуля начинать, если вдруг кто прервал на середине, если не хочется с этим голову морочить.

То есть вполне возможна такая ситуация, твоего говномонстра будут всё время прерывать на середине, он ни разу не выполнится до конца, память покроется дырами фрагментации и кончится, контроллер зависнет, ракета взорвётся на старте и все умрут.

Прости, чувак, ты не прошёл тест тьюринга.

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

Проблема в том, что с большой вероятностью получится ублюдочный кривой говномонстр от SZT.

С чего вдруг. Если мне надо, я изучу вопрос и имеющиеся алгоритмы GC, посмотрю на наличие существующих библиотек их реализующие, если не найду или не подойдут, напишу сам. Почему он получится говномонстром при таком подходе - не очевидно.

Haskell компилируется в код для x86_64, C++ компилируется в код для x86_64, почему бы их не сравнить?

Потому что к функциональным языкм могут быть применимы те алгоритмы GC, которые не применимы к жапке. (Я не сильно вникал в вопрос, но подозреваю что именно в этом и секрет «хорошего GC в haskell и плохого в жабе».)

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

То есть вполне возможна такая ситуация, твоего говномонстра будут всё время прерывать на середине, он ни разу не выполнится до конца, память покроется дырами фрагментации, кончится, контроллер зависнет, ракета взорвётся на старте и все умрут.

Такая ситуация возможна, но ее можно избежать, если выделять память фрагментами, а не жирным куском.

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

С чего вдруг. Если мне надо, я изучу вопрос и имеющиеся алгоритмы GC, посмотрю на наличие существующих библиотек их реализующие, если не найду или не подойдут, напишу сам. Почему он получится говномонстром при таком подходе - не очевидно.

Потому что в C/C++ сама возможность использования GC крайне усложнена повсеместным использованием указателей. Проще взять язык с нативной поддержкой GC.

Потому что к функциональным языкм могут быть применимы те алгоритмы GC, которые не применимы к жапке.

Да, так и есть, иммутабельный доступ к объектам памяти позволяет сравнивать их тупо по указателю. В смысле, объект с меньшим адресом (созданный раньше) гарантированно не будет ссылаться на объект с большим адресом (созданный позже). Как минимум это весьма сильно ускоряет сборку мусора.

Но я всё равно не вижу причины их не сравнить, потому что ВНЕЗАПНО и те и другие языки позволяют писать программы.

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

Такая ситуация возможна, но ее можно избежать, если выделять память фрагментами, а не жирным куском.

Я тебя поздравляю, юный падаван, ты додумался до страничной адресации памяти. Ещё немножко, ты придумаешь SLAB кэш, виртуальную память и прочие ништяки, из-за которых malloc не может выдавать гарантированную задержку и вполне может зависнуть на произвольный промежуток времени, из-за чего в свою очередь твой говномонстр и не может быть применим для hard real fucking time systems.

Добро пожаловать в реальный мир.

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

Да, если не получается какой-то жирный кусок памяти сдвинуть при дефрагментации, это определенно проблема того, кто такой жирный кусок выделил, не рассчитав что его может потребоваться двигать, а времени на это тупо не хватит. Можно еще в самом дефрагментаторе пытаться двигать что-то другое, если этот кусок не поддается.

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

Я до нее не додумался, я про нее знаю. Даже под дос с сегментами какой-то бред пробовал писать. Про виртуальную память тоже знаю, а вот SLAB это что-то новое.

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

Да, если не получается какой-то жирный кусок памяти сдвинуть при дефрагментации, это определенно проблема того, кто такой жирный кусок выделил, не рассчитав что его может потребоваться двигать, а времени на это тупо не хватит.

- Эй, слыш, аллокатор, дай-ка мне массив на 128 элементов.

- Хер тебе а не массив, я его не успею переместить вдруг что. Иди лучше делами займись, пристал тут.

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

Даже под дос с сегментами какой-то бред пробовал писать.

Лучше бы ты учился чему-то полезному, например осилил уже наконец алгоритмы сборки мусора.

SLAB это что-то новое

Это не SLAB что-то новое, это ты баклажан.

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

Не, аллокатор-то пусть выделяет себе. Рано или поздно он может быть и сможет этот жирный кусок памяти скопировать.

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

define полезное
Я вот например под атмегу сделать планировщик через прерывания по таймеру могу, вот это я понимаю круто.

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

Я вот например под атмегу сделать планировщик через прерывания по таймеру могу, вот это я понимаю круто.

Если под «планировщиком через прерывания» ты имеешь ввиду реализацию вытесняющей многозадачности, то это не круто, это курсовая работа для студента второго, максимум третьего курса.

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

Потому что в C/C++ сама возможность использования GC крайне усложнена повсеместным использованием указателей. Проще взять язык с нативной поддержкой GC.

Как повсеместное использование указателей усложняет возможность использования GC? Особенно если откинуть C и ограничиться C++ (тем более C++11)?

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

Как повсеместное использование указателей усложняет возможность использования GC?

Я даже не знаю как это прокомментировать. Самим фактом своего наличия? Тем, что для борьбы с фрагментацией тебе нужно постоянно перемещать куски памяти, указатели на которые ВНЕЗАПНО могут перестать быть валидными?

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

Because the implementation of shared_ptr uses reference counting, circular references are potentially a problem. A circular shared_ptr chain can be broken by changing the code so that one of the references is a weak_ptr.

Вот примерно поэтому RAII может дать тебе по яйцам в самый неожиданный момент.

P.S. К vector это не имеет отношения. В случае с vector я не вижу особых проблем, потому что vector тупой как валенок.

kirk_johnson ★☆
()
Последнее исправление: kirk_johnson (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Если под «планировщиком через прерывания» ты имеешь ввиду реализацию вытесняющей многозадачности, то это не круто, это курсовая работа для студента второго, максимум третьего курса.

У меня высшее образование по другому профилю вообще, я химик. Молекулярно-динамическое моделирование, если интересно

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

Не, аллокатор-то пусть выделяет себе. Рано или поздно он может быть и сможет этот жирный кусок памяти скопировать.

За «рано или поздно» в hard realtime принято давать в морду.

kirk_johnson ★☆
()
Ответ на: комментарий от SZT

Простите, но я тоже по диплому радиофизик (если интересно), но в написании вытесняющего шедуллера по таймеру не вижу ничего крутого (и сам писал, да).

А про GC хотел бы сказать, что если у нас неизвестный набор задач с неизвестными требованиями к памяти (как персональный десктоп, например) - то там или бортовые CG или ручная рулежка с дефрагментацией. А если за ту же АТМегу речь, с четко обозначенными возможными задачами - то проща сразу нарезать\нафрагментировать пул памяти и ничего вообще никуда никогда не перемещать - просто писать куда надо и знать когда оно уже не надо.

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