Здравствуйте, Аноним, Вы писали:
А>для оптимизации было бы полезно делать преобразования кода при выполнении А>например a*b+a*c -> a*(b+c)
В компиляторе после Type4 строится граф выполнения (CFG) и что-то с ним происходит, но для такого преобразования нужно доказывать дистрибутивность операции * над совершенно конкретными операндами.
А>или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
Для таких вещей нужно доказывать коммутативность и прочая.
Это все отлично подходит для дипломной работы, но увы, моя уже закончил универ и занимается более реальными вещами.
Здравствуйте, hardcase, Вы писали:
H>Компилируется и работает. H>Обрати внимание Test вертает X, а не T.
А, сори, сразу смысла не понял.
Ну, дык, это вообще бесполезный код, так как тут просто без дженериков можно было обойтись:
class X
{
public static @+(_ : X, _ : X) : X
{
X()
}
}
module Program
{
Test[T](a : X, b : X) : X
{
a + b
}
}
В обоих случаях работа идет уже с типом X и его наследниками. Компилятор, просто подставит инструкцию приведения типов.
Этот пример не имеет ничего общего с попыткой вызвать оператор для дженерик-типа, что невозможно в рамках донета.
ЗЫ
Еще раз повторюсь. Нужно просто использовать другой подход. Подход принятый в функциональных языках. Операции передавать не через тип, а явно через функции или интерфейсы. При надлежащем подходе к проектированию результат будет не чуть не хуже.
А вот переть против рантайма и пытаться эмулировать недостающую функциональность — это занятие не благодарное.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>Вообще то в начале я написал
А>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c) А>fun1(fun2(x:int,y:int),y) -> fun1(x, fun2(x,y))
Что-то я не видел слова Matrix в начале топика. К тому же нужно обладать определенным знанием об устройстве этого класса.
А>довольно сильная оптимизация
И при том элементарно реализуемая человеком.
Может быть лучше мы будем заниматься действительно реальными вещами?
Здравствуйте, Аноним, Вы писали:
А>помойму вы не понимаете чем занимается jit, откуда он может знать что допустима такая замена?
А>fun1(fun2(x,y),y) -> fun1(x, fun2(x,y))
А>и причем тут вообще процессор?
Процессор исполняет код.
А>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)
А>откуда jit может знать что для класса Matrix допустима такая оптимизация?
Второй круг? Откуда компилятор может знать что для матрицы такая оптимизация допустима?
/* иЗвиНите зА неРовнЫй поЧерК */
Преобразование выражений
От:
Аноним
Дата:
27.09.10 05:30
Оценка:
для оптимизации было бы полезно делать преобразования кода при выполнении
например a*b+a*c -> a*(b+c)
или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
Re[2]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 06:06
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>для оптимизации было бы полезно делать преобразования кода при выполнении А>>например a*b+a*c -> a*(b+c)
H>В компиляторе после Type4 строится граф выполнения (CFG) и что-то с ним происходит, но для такого преобразования нужно доказывать дистрибутивность операции * над совершенно конкретными операндами.
А>>или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
H>Для таких вещей нужно доказывать коммутативность и прочая.
H>Это все отлично подходит для дипломной работы, но увы, моя уже закончил универ и занимается более реальными вещами.
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Вообще то в начале я написал
А>>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c) А>>fun1(fun2(x:int,y:int),y) -> fun1(x, fun2(x,y))
H>Что-то я не видел слова Matrix в начале топика. К тому же нужно обладать определенным знанием об устройстве этого класса.
А>>довольно сильная оптимизация
H>И при том элементарно реализуемая человеком.
H>Может быть лучше мы будем заниматься действительно реальными вещами?
проблема в том что человеку зачастую надо знать внутренности класса, а эти шаблонные оптимизации поверх.
Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
Здравствуйте, Аноним, Вы писали:
А>проблема в том что человеку зачастую надо знать внутренности класса, а эти шаблонные оптимизации поверх.
Компилятору точно также необходимо знать. И не просто знать, а доказать то, что продемонстрированные оптимизации инвариантны вычисленному результату. Во многом эта задача пересекается с доказательством отсутствия побочных эффектов, чего компилятор сейчас делать не умеет.
А>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
Здравствуйте, hardcase, Вы писали:
А>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
H>В вот это точно не в наш форум.
Макросы-операторы работают в генериках, а вот обычные обработчики операторов — это статические методы, как-то не слишком ясно как их применять там.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[7]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 06:49
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, hardcase, Вы писали:
А>>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
H>>В вот это точно не в наш форум.
H>Макросы-операторы работают в генериках, а вот обычные обработчики операторов — это статические методы, как-то не слишком ясно как их применять там.
macros fun(t:T) request<T*T> ....
Данный макрос выдаст ошибку еслидля типа T не определена операция умножения
argument T request operation T*T....
Здравствуйте, Аноним, Вы писали:
А>Данный макрос выдаст ошибку еслидля типа T не определена операция умножения А>argument T request operation T*T....
Ок. Перефразирую: как в .NET задать ограничение на наличие в параметре генерика T некоторого статического члена S?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 06:54
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>проблема в том что человеку зачастую надо знать внутренности класса, а эти шаблонные оптимизации поверх.
H>Компилятору точно также необходимо знать. И не просто знать, а доказать то, что продемонстрированные оптимизации инвариантны вычисленному результату. Во многом эта задача пересекается с доказательством отсутствия побочных эффектов, чего компилятор сейчас делать не умеет.
А>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
H>В вот это точно не в наш форум.
А зачем компилятору доказывать инвариантность выражений?
Тот кто описал операцию, тот и доказывает.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, hardcase, Вы писали:
А>>>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
H>>>В вот это точно не в наш форум.
H>>Макросы-операторы работают в генериках, а вот обычные обработчики операторов — это статические методы, как-то не слишком ясно как их применять там.
А>macros fun(t:T) request<T*T> ....
А>Данный макрос выдаст ошибку еслидля типа T не определена операция умножения А>argument T request operation T*T....
Вполне рабочий код:
class X
{
public static @+(_ : X, _ : X) : X
{
X()
}
}
module Program
{
Test[T](a : T, b : T) : X where T : X
{
a + b
}
}
/* иЗвиНите зА неРовнЫй поЧерК */
Re[9]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 07:00
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Данный макрос выдаст ошибку еслидля типа T не определена операция умножения А>>argument T request operation T*T....
H>Ок. Перефразирую: как в .NET задать ограничение на наличие в параметре генерика T некоторого статического члена S?
причем тут нет?
С помощью рефлекшен проверять при развороте макроса.
Насколько я знаю макросы не работают в самом нете, а работают при компиляции
Здравствуйте, Аноним, Вы писали:
А>С помощью рефлекшен проверять при развороте макроса.
Проверку наличия операторов в типах осуществляет типизатор. Если тип не поддерживает некоторого оператора, значит макрос к нему не применим — будет ошибка компиляции.
Пример случая применимости оператора в генерике я показал выше.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[9]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 07:05
Оценка:
module Program
{
Test[T](a : T, b : T) : Т request(T+T)
{
a + b
}
}
При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
Здравствуйте, Аноним, Вы писали:
А> module Program А> { А> Test[T](a : T, b : T) : Т request(T+T) А> { А> a + b А> } А> } А>При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
Здравствуйте, Аноним, Вы писали:
А> module Program А> { А> Test[T](a : T, b : T) : Т request(T+T) А> { А> a + b А> } А> } А>При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
Ну и код несколько бессмысленнен — у произвольного типа T оператор + не определен. И это не ограничение Немерле, это ограничение .NET.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[11]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 07:14
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>> module Program А>> { А>> Test[T](a : T, b : T) : Т request(T+T) А>> { А>> a + b А>> } А>> } А>>При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
H>Что такое request(T+T) ?
на этапе компиляции делается проверка существования операции T+T и в случае ее не возможности выдается сообщение
"для макроса Test[T](a : T, b : T) : Т требуется операция T+T"
Re[7]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 09:11
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, Аноним, Вы писали:
А>>>проблема в том что человеку зачастую надо знать внутренности класса, а эти шаблонные оптимизации поверх.
H>>Компилятору точно также необходимо знать. И не просто знать, а доказать то, что продемонстрированные оптимизации инвариантны вычисленному результату. Во многом эта задача пересекается с доказательством отсутствия побочных эффектов, чего компилятор сейчас делать не умеет.
А>>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
H>>В вот это точно не в наш форум.
А>А зачем компилятору доказывать инвариантность выражений? А>Тот кто описал операцию, тот и доказывает.
просто макросами этого не сделать, а в сложных операциях выгрыш будет большой
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, Аноним, Вы писали:
А>>> module Program А>>> { А>>> Test[T](a : T, b : T) : Т request(T+T) А>>> { А>>> a + b А>>> } А>>> } А>>>При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
H>>Что такое request(T+T) ?
А>на этапе компиляции делается проверка существования операции T+T и в случае ее не возможности выдается сообщение А>"для макроса Test[T](a : T, b : T) : Т требуется операция T+T"
Это как бы вообще не макрос — это обычный метод. Ошибка сейчас и так выдается.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[13]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 09:56
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, hardcase, Вы писали:
H>>>Здравствуйте, Аноним, Вы писали:
А>>>> module Program А>>>> { А>>>> Test[T](a : T, b : T) : Т request(T+T) А>>>> { А>>>> a + b А>>>> } А>>>> } А>>>>При вызове макроса он поругается не на какую то внутренность например на a+b в макросе, а на сам макрос
H>>>Что такое request(T+T) ?
А>>на этапе компиляции делается проверка существования операции T+T и в случае ее не возможности выдается сообщение А>>"для макроса Test[T](a : T, b : T) : Т требуется операция T+T"
H>Это как бы вообще не макрос — это обычный метод. Ошибка сейчас и так выдается.
где выдается? в указании на макрос или в нутрях его на строчку?
Здравствуйте, Аноним, Вы писали:
А>для оптимизации было бы полезно делать преобразования кода при выполнении А>например a*b+a*c -> a*(b+c)
А>или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
Такими оптимизациями занимается jit. Не надо ему мешать. Может оказаться, что в современны процессарах первый вариант кода будет выполняться быстрее, так как будет распараллелен. Джит пишут не дураки. Им виднее нужно это дело оптимизировать или нет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>macros fun(t:T) request<T*T> ....
А>Данный макрос выдаст ошибку еслидля типа T не определена операция умножения А>argument T request operation T*T....
Макросы немерла оперируют с нетипизированным АСТ. Тип можно вычислить внутри макры, но указать его в параметрах нельзя.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>С помощью рефлекшен проверять при развороте макроса. А>Насколько я знаю макросы не работают в самом нете, а работают при компиляции
Для макросов и проверять ничего не надо. Им по фику что есть, а чего нет. Они генерируют код который потом скомпилируется компилятором. Если в конечном типе есть нужные методы, то все скомпилируется. Короче, можно считать, что мы имеем дело с утиной типизацией аля шаблоны С++. Да у макросов и шаблонов плюсов и корни похожие (обе технологии работают на уровне АСТ). Только макросы несравнимо гибче.
Но именно по этому макросы не могут налагать ограничения на типы параметров. Ведь параметры — это AST.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hardcase, Вы писали:
H>Вполне рабочий код:
H>
H> class X
H> {
H> public static @+(_ : X, _ : X) : X
H> {
H> X()
H> }
H> }
H> module Program
H> {
H> Test[T](a : T, b : T) : X where T : X
H> {
H> a + b
H> }
H> }
H>
Совершенно не рабочий в рамках дженериков дотнета.
Ну, и макросы тут вообще отсутствуют.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>на этапе компиляции делается проверка существования операции T+T и в случае ее не возможности выдается сообщение А>"для макроса Test[T](a : T, b : T) : Т требуется операция T+T"
Вот это "требуется операция T+T" недопустимо в рамках дженериков дотнета. Так уж они спроектированы. Можно только интерфейсы в качестве ограничений использовать.
Ну, и немерл просто использует дотнетные дженерики чтобы быть совместимым со всеми языками дотнета.
В подобных случаях поступать нужно следующим образом. Нужно вводить функциональный параметр/поле или интерфейс который будет предоставлять реализацию нужной операции. При таком подходе, приведенный пример можно переписать следующим образом:
class X
{
public static @+(_ : X, _ : X) : X
{
X()
}
}
module Program
{
Test[T](a : T, b : T, add : T * T -> T) : X
{
add(a, b)
}
Main() : void
{
Test(X(), X(), _ + _);
}
}
В классах такие фунциональные объекты можно хранить в полях.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>просто макросами этого не сделать, а в сложных операциях выгрыш будет большой
Думаю, что в следующей версии компилятора мы выделим стадию компиляции так, что кто угодно сможет делать плагины к ней и встраивать свои оптимизации. Тогда те кому надо смогу делать собственные локальные оптимизации. Ну, а удачные (что-то дающие и не приводящие к проблемам) можно будет вставлять в компилятор.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Преобразование выражений
От:
Аноним
Дата:
27.09.10 18:43
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>Кроме того хорошо бы ввести требования на наличия в генериках операций применимым к операндам...
VD>Это к Майкрософт. Если не ошибаюсь, они хотели ввести интефейсы вроде IAddable для всроенных типов. Но когда и где я не в курсе.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, hardcase, Вы писали:
H>>Вполне рабочий код:
H>>
H>> class X
H>> {
H>> public static @+(_ : X, _ : X) : X
H>> {
H>> X()
H>> }
H>> }
H>> module Program
H>> {
H>> Test[T](a : T, b : T) : X where T : X
H>> {
H>> a + b
H>> }
H>> }
H>>
VD>Совершенно не рабочий в рамках дженериков дотнета. VD>Ну, и макросы тут вообще отсутствуют.
Компилируется и работает.
Обрати внимание Test вертает X, а не T.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Преобразование выражений
От:
Аноним
Дата:
28.09.10 04:28
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>для оптимизации было бы полезно делать преобразования кода при выполнении А>>например
А>>или и т д
VD>Такими оптимизациями занимается jit. Не надо ему мешать. Может оказаться, что в современны процессарах первый вариант кода будет выполняться быстрее, так как будет распараллелен. Джит пишут не дураки. Им виднее нужно это дело оптимизировать или нет.
помойму вы не понимаете чем занимается jit, откуда он может знать что допустима такая замена?
fun1(fun2(x,y),y) -> fun1(x, fun2(x,y))
и причем тут вообще процессор?
a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)
откуда jit может знать что для класса Matrix допустима такая оптимизация?
Re[4]: Преобразование выражений
От:
Аноним
Дата:
28.09.10 06:55
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>помойму вы не понимаете чем занимается jit, откуда он может знать что допустима такая замена?
А>>fun1(fun2(x,y),y) -> fun1(x, fun2(x,y))
А>>и причем тут вообще процессор?
H>Процессор исполняет код.
А>>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)
А>>откуда jit может знать что для класса Matrix допустима такая оптимизация?
H>Второй круг? Откуда компилятор может знать что для матрицы такая оптимизация допустима?
Здравствуйте, Аноним, Вы писали:
А>Третий круг. Потому что я указал
Мы на разных форумах общаемся? Ни в одном вашем сообщении небыло означенного псевдокода:
А>class Matrix А>( А> operator @* .... А> operator @+ .... А> optimization(a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)) А>}
Ну и опять же, что-то сомнительно что это будет полезно.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Преобразование выражений
От:
Аноним
Дата:
28.09.10 09:28
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Третий круг. Потому что я указал
H>Мы на разных форумах общаемся? Ни в одном вашем сообщении небыло означенного псевдокода:
А>>class Matrix А>>( А>> operator @* .... А>> operator @+ .... А>> optimization(a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)) А>>}
H>Ну и опять же, что-то сомнительно что это будет полезно.
Здравствуйте, Аноним, Вы писали:
А>помойму вы не понимаете чем занимается jit,
Предположение не верное.
А> откуда он может знать что допустима такая замена?
Он работает с типизированной стековой машиной, так что ему известны типы аргументов. Ну, и сделать предположение о целых числах ему точно не составит труда.
Делать такие предположения для пользовательских объектов джит конечно не может. Но этого никто кроме автора этого кода не имеет права делать.
А>fun1(fun2(x,y),y) -> fun1(x, fun2(x,y))
А>и причем тут вообще процессор?
Ну, не знаю. Может быть потому что он производит реальное исполнение кода?
А>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)
А>откуда jit может знать что для класса Matrix допустима такая оптимизация?
Ни откуда. Только если код этого Matrix будет заинлайнен и превратится в набор примитивных операций.
Если для вашего Matrix нужны какие-то оптимизации, то имеет смысл сделать их самостоятельно.
Кстати, это можно сделать на макросах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>Третий круг. Потому что я указал
А>class Matrix А>( А> operator @* .... А> operator @+ .... А> optimization(a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)) А>}
Ты забыл упомянут, что возможность оптимизации нужно описывать явно самому пользователю.
В таком виде это конечно возможно. Вот только имеет ли смысл тратить не мало времени на доработку компилятора только ради того, чтобы научить его работать с фичей которая нужна раз в код по обещанию и может быть спокойно оптимизирована вручную?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
А>как минимум не вредно...
Делать серьезный объем работы только на основании, что что-то не вредно, явно не разумно.
Для реализации фичи в языке нужны очень серьезные основания. Иначе конца и края не будет работе над подобными фичами. Плюс язык превратится в помойку и его не сможет выучить даже самый пытливый ум.
А>теперь нужно уже
Кому и зачем?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Преобразование выражений
От:
Аноним
Дата:
29.09.10 08:20
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>помойму вы не понимаете чем занимается jit,
VD>Предположение не верное.
А>> откуда он может знать что допустима такая замена?
VD>Он работает с типизированной стековой машиной, так что ему известны типы аргументов. Ну, и сделать предположение о целых числах ему точно не составит труда.
VD>Делать такие предположения для пользовательских объектов джит конечно не может. Но этого никто кроме автора этого кода не имеет права делать.
А>>fun1(fun2(x,y),y) -> fun1(x, fun2(x,y))
А>>и причем тут вообще процессор?
VD>Ну, не знаю. Может быть потому что он производит реальное исполнение кода?
А>>a:Matrix*b:Matrix+a*c:Matrix -> a*(b+c)
А>>откуда jit может знать что для класса Matrix допустима такая оптимизация?
VD>Ни откуда. Только если код этого Matrix будет заинлайнен и превратится в набор примитивных операций. VD>Если для вашего Matrix нужны какие-то оптимизации, то имеет смысл сделать их самостоятельно. VD>Кстати, это можно сделать на макросах.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, VladD2, Вы писали:
VD>>Кстати, это можно сделать на макросах.
А>Как это можно сделать в макросах?
Типизируем выражение и преобразоваываем его в соответствии с переместительным и сочетательным законом арифметики.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Преобразование выражений
От:
Аноним
Дата:
29.09.10 08:40
Оценка:
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, VladD2, Вы писали:
VD>>>Кстати, это можно сделать на макросах.
А>>Как это можно сделать в макросах?
H>Типизируем выражение и преобразоваываем его в соответствии с переместительным и сочетательным законом арифметики.
Здравствуйте, Аноним, Вы писали:
А>Как это можно сделать в макросах?
Если сами вычисления буду передаваться в некий макрос, то не трудно будет разобрать выражния и переставить их содержимое как требуется.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Преобразование выражений
От:
Аноним
Дата:
29.09.10 09:57
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Аноним, Вы писали:
А>>Как это можно сделать в макросах?
VD>Если сами вычисления буду передаваться в некий макрос, то не трудно будет разобрать выражния и переставить их содержимое как требуется.
Здравствуйте, Аноним, Вы писали:
А>для оптимизации было бы полезно делать преобразования кода при выполнении А>например a*b+a*c -> a*(b+c)
А>или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
Я всегда думал, что алгеброй должен все-таки заниматься программист, а не компилятор.
Если вы знаете, что для вашего типа данных сумма произведений рассчитывается быстрее, чем произведение суммы, так и напишите в своем коде.
Re[2]: Преобразование выражений
От:
Аноним
Дата:
29.09.10 12:29
Оценка:
Здравствуйте, catbert, Вы писали:
C>Здравствуйте, Аноним, Вы писали:
А>>для оптимизации было бы полезно делать преобразования кода при выполнении А>>например a*b+a*c -> a*(b+c)
А>>или fun1(fun2(x,y),y) -> fun1(x, fun2(x,y)) и т д
C>Я всегда думал, что алгеброй должен все-таки заниматься программист, а не компилятор. C>Если вы знаете, что для вашего типа данных сумма произведений рассчитывается быстрее, чем произведение суммы, так и напишите в своем коде.
Cjгласен, если только по вашему мнению и программист должен назначать регистры.
Просьба, цитировать только то на что отвечаешь.
VD>>Ни откуда. Только если код этого Matrix будет заинлайнен и превратится в набор примитивных операций. VD>>Если для вашего Matrix нужны какие-то оптимизации, то имеет смысл сделать их самостоятельно. VD>>Кстати, это можно сделать на макросах.
А>Как это можно сделать в макросах?
Скажем обрамить вычисление некой мкрой:
def result = Optimize(x * a + x * b);
А в этом макре уже анализировать код и делать нужные его трансформации.
Можно поступить сложнее. Повесить макрос на функцию, чтобы он выискивал в теле функции то что сможет оптимизировать.
Но вообще, это конечно баловство.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
VD>>Если сами вычисления буду передаваться в некий макрос, то не трудно будет разобрать выражния и переставить их содержимое как требуется.
А>Таким образом мы обязаны обертывать все в макрос?
При таком подходе — да. Но в принципе может оказаться, что это не так уж и сложно. Ведь макросу можно дать синтаксис вроде того что используется для checked.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Аноним, Вы писали:
C>>Если вы знаете, что для вашего типа данных сумма произведений рассчитывается быстрее, чем произведение суммы, так и напишите в своем коде.
А>Cjгласен, если только по вашему мнению и программист должен назначать регистры.
Это разные уровни абстракции. Если бы я писал на ассемблере, и он бы начал сам менять мой код и переназначать регистры, я бы выкинул такой ассемблер на свалку. Если бы я написал ваше выражение на матлабе, а он бы не упростил его, я бы тоже удивился.
Но на уровне компилятора языка общего назначения, каким является Немерле, такие оптимизации ИМХО недопустимы. Ведь если данное выражение было бы частью LINQ-выражения, компилятор бы генерировал явно некорректный код. Если бы тип данных не подчинялся дистрибутивному закону умножения, компилятор опять бы генерировал некорректный код. Если я хотел бы посмотреть в окне отладчика подвыражения a*b и a*c, я удивился бы тому что увидел.
Конечно можно было бы проводить оптимизацию только для релиз-билдов, только для il-кода (а не для внутреннего представления кода), и только если такое поведение явно разрешено. Но представьте себе ситуацию, когда в классе Matrix есть баг, из-за которого при умножении больших чисел генерируется исключение. В Debug-режиме все тесты проходят. Но как только вы выкладываете код на сервер, выскакивает exception. Вы садитесь проверять дебаг-билд, а там исполняется другой код, и все чисто.
Да и если говорить только о double-ах, если a — маленькое число, а b и c — большие, с разными знаками, и приблизительно равны по модулю, ваша оптимизация может убить точность вычисления.
Я не говорю, что в Nemerle не осталось места для оптимизаций. Просто где-то нужно провести линию. И, как по мне, эта линия намного ниже по стеку абстракций, чем аксиомы алгебр и теории чисел.
Здравствуйте, catbert, Вы писали:
C>Но на уровне компилятора языка общего назначения, каким является Немерле, такие оптимизации ИМХО недопустимы. Ведь если данное выражение было бы частью LINQ-выражения, компилятор бы генерировал явно некорректный код. Если бы тип данных не подчинялся дистрибутивному закону умножения, компилятор опять бы генерировал некорректный код. Если я хотел бы посмотреть в окне отладчика подвыражения a*b и a*c, я удивился бы тому что увидел.
Не, ну, тут товарищ предлагал вполне рабочее решение — декларативно описывать возможность (и алгоритм) оптимизации прямо в типе для которого определены операторы.
Против такого решения лично я не возражаю. Просто фича не той важности чтобы ею заняться лично. Но если кто-то сделал бы, был бы только "за".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Не, ну, тут товарищ предлагал вполне рабочее решение — декларативно описывать возможность (и алгоритм) оптимизации прямо в типе для которого определены операторы.
Тот же вопрос. Нахрена описывать возможности оптимизации прямо в типе, если можна прописать прямо оптимально в коде?
VD>Против такого решения лично я не возражаю. Просто фича не той важности чтобы ею заняться лично. Но если кто-то сделал бы, был бы только "за".
Да я тоже не возражаю. Просто не понимаю, какой в ней смысл. Ведь макрос не делает больше того, что может сделать программист. Он просто уменьшает количество работы для программиста. А тут никакого уменьшения нет.
Здравствуйте, catbert, Вы писали:
C>Тот же вопрос. Нахрена описывать возможности оптимизации прямо в типе, если можна прописать прямо оптимально в коде?
Наверно, чтобы не делать это по много раз.
VD>>Против такого решения лично я не возражаю. Просто фича не той важности чтобы ею заняться лично. Но если кто-то сделал бы, был бы только "за".
C>Да я тоже не возражаю. Просто не понимаю, какой в ней смысл. Ведь макрос не делает больше того, что может сделать программист. Он просто уменьшает количество работы для программиста. А тут никакого уменьшения нет.
Ну, автоматизация оптимизации — это тоже устранение лишней работы.
Так что некоторое рациональное зерно в этом есть. Вот только боюсь, что востребована фича будет очень редко, а труда на нее уйдет много.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.