В ходе всех этих развлечений с оптимизациями обнаружился интересный, но очень неприятный эффект. Результат вычислений для разных компиляторов и разных флагов оптимизации порой значительно менялся.
Для более удобного наблюдения этого эффекта был выбран простой пример(полный код на github):
1 2 3 4 5 |
int i; long double res; for(i=0;i<100000000;i++){ res += cos(i); } |
В этом маленьком тесте изменение результата от изменения флагов обнаружить не удалось, но всё равно обилие результатов удивляет — 5 различных, с 13 совпадающими знаками из 15-17 возможных для double.
Исходник и компилятор | Результат | Время выполнения, с |
Assembler | 1.53436944477410652787 | 3.81 |
gcc long | 1.53436944477462278158 | 4.4 |
gcc double | 1.53436944477389380914 | 4.4 |
icc long | 1.53436944477397574360 | 6.88 |
icc double | 1.53436944477334602510 | 1.50 |
*результаты по одному измерению, по этому совсем серьёзно воспринимать их не стоит. Время указано для процессора FX-8120
p.s. ну и обнаружилось, что написание кода на ассемблере пока ещё не абсолютно потеряло смысл — получился до 15% быстрее, чем на C.