пятница, 4 июля 2014 г.

Не все перемещения на регистр одинаково полезны

Словил забавную багу (а может и не багу) оптимизатора на казалось бы простеньком примере:

$ cat t.c
#include <stdio.h>

typedef double t;

t a = 0.5;
t b = 0.23;
t c = 6.0;

int main (void)
{
  t e, f;

  e = a - b;
  f = e * c;

  printf ("%.30f\n", f);
  return 0;
}

$ gcc t.c -O2 && ./a.out && gcc t.c && ./a.out
1.619999999999999884536805438984
1.620000000000000106581410364015


Такой эффект наблюдается с совершенно бородатых времён (ещё по-моему gcc-2.x такое выдавал). И наблюдается он только на 32-битном x86.

Сначала я думал, что это вина gcc, особенно с учётом того что llvm отрабатывает нормально. Но я эту багу нашёл в багзилле, суть вот в чём. Без оптимизации компилятор хранит double переменные на стеке, там они занимают положенные 64 бита и всё хорошо. А при включённой оптимизации он перемещает значение на плавающий регистр, который имеет размер 80 бит.

На вики есть объяснение почему именно 80 бит. Это связано с тем, что для удвоения точности экспоненту нужно увеличить на 1 бит и получить 12 бит, а мантиссу до 77 вместо старых 55 бит. Решение довольно спорное, т.к. оно не портируемое. Т.е. программе для того чтобы результат в разных режимах на разных машинах выдавал одинаковый результат нужно весьма извращаться. Иногда помогает ключ -ffloat-store, который запрещает хранить плавающие значения на регистрах.

пятница, 23 мая 2014 г.

Векторизация в компиляторе Эльбруса

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

четверг, 1 мая 2014 г.

Про оптимизации, безопасность и "нормальные языки".

В конце 2013 года вышла довольно интересная статья "Towards Optimization-Safe Systems: Analyzing the Impact of Undefined Behavior" про то как компиляторы, применяя различные агрессивные оптимизации убирают проверки безопасности. Хочу поделиться своими мыслями на этот счёт.

пятница, 28 марта 2014 г.

Эльбрусы. Новые и не очень.

Недавно сгонял на выставку "Новая электроника - 2014", где меня целенаправленно интересовал стенд МЦСТ. Особенностью этого стенда было то, что на нём представлен новый процессор "Эльбрус-4С". Он нём и ещё о паре забавных железок расскажу под катом.

суббота, 21 декабря 2013 г.

Шпаргалка по сборке gcc

Оставлю тут шпаргалку по сборке gcc из транка:

$ # скачаем исходники
$ svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc
$ cd gcc
$ # соберём компилятор
$ mkdir obj bin
$ cd obj
$ ../configure
$ make -j2
$ make DESTDIR=/anywhere/gcc/bin/ install
$ # а теперь пересоберём его самим собой, но с уже интересующими нас опциями
$ make clean
$ rm * -rf
$ ../configure CC="
/anywhere/gcc/bin/usr/local/bin/gcc" CXX="/anywhere/gcc/bin/usr/local/bin/g++" CFLAGS="$CFLAGS -O3" CXXFLAGS="$CXXFLAGS -O3" LIBS="-L/anywhere/gcc/bin/usr/local/libs $LIBS"
$ make -j2
$ make DESTDIR=
/anywhere/gcc/bin_opt/ install

понедельник, 18 ноября 2013 г.

Установка Gentoo на шифрованный раздел

Решил поэкспериментировать с шифрованием разделов в gentoo. Т.к. не нашлось готовых мануалов, по которым бы всё сразу завелось пришлось долго гуглить и ходить по граблям. В посте будет полное описание данного процесса. Нет, не неуклюжего хождения по граблям, а готового решения, которое сработало на моём ноутбуке.

пятница, 1 ноября 2013 г.

Ошибка в комментарии

На старых фронтэндах был простой способ получить ошибку в плохо написанном комментарии. Связано это с триграфами. Сам столкнулся с такой на старой версии edg - фронтэнда, который используется в компиляторе intel.

$ cat test.c

/**
 * ??!
 */

int main(){}


$ lcc_i test.c
lcc: "test.c", line 2: error: support for trigraphs is disabled
          [-Werror=trigraphs]
   * ??!
     ^

1 error detected in the compilation of "test.c".


Подробней о проблемах с триграфами можно почитать на вики. Тут интересен вопрос "а почему вообще возникает такая проблема?". Фишка кроется в стандарте, раздел 5.1.1.2 Translation phases. Грубо говоря препроцессирование делится на 6 стадий. При этом триграфы разворачиваются на первой стадии, а комментарии удаляются только на 3-ей.

На современных компиляторах такой проблемы замечено не было.