Pull to refresh
542
-7.2

Довожу здравый смысл до абсурда

Send message

Интересно, что функции типа sin и ln набраны италиком, что недопустимо. Надо бы поправить sympy...

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

Я чётко сказал "оригинал текста". Ваш текст - это не компиляция всех вами приведённых ссылок, а творческая переработка одного-двух источников.

Сюжет захватывающий, но это не отменяет необходимости аккуратной работы с источниками.

Да ладно вам, дайте уже придраться ;)

Я-то свои плюсы поставил.

Производная x^2 равна не 2, а 2x, если что.

А ссылку на оригинал текста ставить нынче не модно?

https://boehs.org/node/everything-i-know-about-the-xz-backdoor

Сейчас распараллеливание вычислений есть просто везде.

Кроме того, мы же нейросети обсуждали? Вы вот сейчас серьезно представили сетку в один тред? :)

И даже на одной и той же машине порядок меняется.

Нет. Результат операций с плавающей точкой зависит от порядка операций: в общем случае (a+b)+c != a+(b+c). Распараллелить вычисления, гарантируя стабильный порядок операций - это очень сложная задача, которая решается крайне редко, только в критических случаях.

Можно я буду пользоваться комментариями в качестве личных заметок при чтении ваших статей? Вы дали ссылку на файл SROA.cpp, и выясняется, что SROA - это Scalar Replacement Of Aggregates. Очень интересное и говорящее название! Давайте отвлечёмся от финод, и посмотрим на более простой случай.

Мне кажется, что инлайнинг функций - это вид SROA (даже если в том .cpp его нет), только оно работает над кодом, а не над памятью. Если мы возьмём такой код, то инлайнинг позволяет избавиться от вызова print:

Hidden text
typedef struct {
  int x, y;
} point;

void print(point *p) {
  printf("(%d, %d)", p->x, p->y);
}

int main () {
  point p;
  p.x = 1;
  p.y = 2;
  print (&p);
  return 0;
}

То есть, после инлайнинга мы получим следующий код:

Hidden text
typedef struct {
  int x, y;
} point;

int main () {
  point p;
  p.x = 1;
  p.y = 2;
  printf("(%d, %d)", p.x, p.y);
  return 0;
}

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

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

То есть, польза в том, что мы не обязаны использовать load/store для доступа к полям структуры: SROA позволяет убрать агрегатную структуру point, и заменить её на две локальных переменных p_x и p_y:

Hidden text
int main () {
  int p_x = 1;
  int p_y = 2;
  printf("(%d, %d)", p_x, p_y);
  return 0;
}

А дальше проталкивание констант позволяет убрать и их:

Hidden text
int main () {
  printf("(%d, %d)", 1, 2);
  return 0;
}

Возвращаясь к данной статье, автор рассматривает фрейм функции как агрегатную структуру с параметрами и локальными переменными, и заменяет где можно доступ к этой структуре через load/store на SSA-значения. А это, в свою очередь, уже позволит компилятору делать рассуждения.

  • Для начала, из графа удаляются все обратные рёбра циклов. Они нам не потребуются. Дальше рассматриваем граф без обратных рёбер.

На всякий случай, если кто тоже споткнулся, то это определение дано через одну статью :)

да, согласен, спасибо

В прод - безусловно. Для обучения - сильно не факт

Можно отбивку пробелом использовать, наверное

Ну, если даже GCC не стесняется генерировать ассемблер :)

А почему последний икс в скобках?

Я-то запустил, и не только хелловорлд :)

А зависимости это... Неопрятненько, что ли. Кусок магии остаётся, нет чувства полного удовлетворения.

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

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

Да кто ж будет игрушечный компилятор транслировать под каждую архитектуру? Лично мне нравятся проекты без внешних зависимостей, зачем в учебном коде llvm?

Да не надо на меня никаких ссылок, пользуйтесь, если найдёте пользу.

1
23 ...

Information

Rating
Does not participate
Registered
Activity