Re[6]: вдогонку
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.10.08 04:39
Оценка: +3
S>Осталось понять, можно ли применить этот подход, оставаясь в рамках "наилучшим образом оптимизированной программы, написанной на ассемблере", и "можно ли сделать код эффективнее с помошью каких-то высокоуровневых конструкций". Об этом я напишу завтра, потому что сегодня пора домой
Итак, продолжаем разрывать шаблоны. Но перед тем, как перейти к основному обсуждению, сделаю два уточнения:
1. Напомню, что речь идет именно о сферических программах в вакууме. Мы не собираемся обсуждать возможности реально доступных компиляторов и сред исполнения. Во-первых, потому, что изначально вопрос формулировался именно в абстрактно-теоретических терминах, а во-вторых, потому, что иначе нам придется сравнивать реальные компиляторы с реальными программистами-ассемблерщиками, и тут совершенно неясно, слон кита заборет или всё-таки наоборот

2. Как совершенно верно заметил Pzz, моё утверждение про эффективность адаптивного алгоритма слишком сильное. Действительно, нужно оговориться: мы выиграем только в том случае, когда цена выбора оптимального решения не превышает проигрыш от применения неоптимального.
Тем не менее, на справедливость остальных умозаключений это не влияет: дело в том, что мне не нужно доказывать, что этот подход будет пределом эффективности. Мне достаточно показать, что существуют задачи, на которых он эффективнее.

Итак, вернемся к нашим "высокоуровневым конструкциям".
Пока что мы получили интуитивное представление о том, что неплохо бы выбирать решение в зависимости от свойств поступающих задач. Ассемблер достаточно гибок для того, чтобы помочь нам в простых случаях. Под простыми случаями я имею в виду такие, когда количество вариантов решения невелико. Ну вот сколько у нас алгоритмов сортировки для массива? В таком случае, расходы памяти на одновременное хранение всех этих программ не выходят за пределы разумного, а выбор сводится к традиционному conditional statement.

К сожалению, у этого подхода имеются свои ограничения.
Если "размеры" семейства программ-решений выходят за разумные пределы, то их суммарный объем становится препятствием для статической реализации. Это не такая уж редкая ситуация: как правило, некоторая задача делится на более мелкие подзадачи. Если у подзадач A1 и A2 — по четыре решения, то у задачи A, которая является суперпозицией этих двух задач, получается 16 решений.
В более сложных случаях мы можем наблюдать экспоненциальный взрыв пространства возможных решений. Реальный пример желающие могут пронаблюдать здесь.

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

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

В принципе, вопрос можно считать решенным, но на всякий случай я продолжу разжевывание — практика показала, что даже высокообразованные люди совершенно неспособны самостоятельно строить логические цепочки, особенно когда им этого не хочется.

Итак, изначальный вопрос пользовался "высокоуровневыми конструкциями", а не "runtime code generation".
Поясняю логическую взаимосвязь: вот у нас есть та часть программы, которая не меняется в процессе ее работы. И вот есть другая часть программы, которая таки меняется в процессе работы. На чем написана эта вторая часть? Я имею в виду — до того, как мы начали программу выполнять?

На ассемблере? Нет, это не лучшая идея.
На ассемблере ее написать нельзя — потому, что сам ассемблер не содержит достаточно информации о том, какие трансформации можно над ним проводить. Ну, если быть точным, то для ограниченного количества вырожденных случаев всё-таки можно обойтись ассемблером — соблюдая специальные конвенции, чтобы обеспечить "совместимость" кусочков программы, из которых собирается конечное решение.
Но в общем случае помимо собственно ассемблерного "образца" статической части программы понадобится какая-то еще информация о его устройстве: какие части образца можно менять, куда их можно встраивать, и так далее. Эта информация как раз эквивалентна более высокоуровневым конструкциям, чем сам язык ассемблера.

Вот, собственно, и всё. Sapienti Sat.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.