LINUX.ORG.RU

Есть идеи как улучшить?

 


1

2

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

Ответ на: комментарий от fsb4000

Тогда просто не поймёшь чем этот код
[code=c]return (f - 32.0) * (5.0/9.0);[/code]
лучше вот этого
[code=c]return (f - 32.0) * 5.0/9.0;[/code]

Первый код кодируется тремя командами.

[skip]

Второй код кодируется четыремя командами

[skip]

Не один компилятор не оптимизирует второй код до первого, при любом уровне оптимизации компилятора.

double f1(double f)
{
  return (f - 32.0) * (5.0/9.0);
}

double f2(double f)
{ 
  return (f - 32.0) * 5.0/9.0;
}
gcc -S -O3 -funsafe-math-optimizations test_mmx1.c
cat test_mmx1.s
        .file   "test_mmx1.c"
        .section        .text.unlikely,"ax",@progbits                                                                                                                               
.LCOLDB2:                                                                                                                                                                           
        .text                                                                                                                                                                       
.LHOTB2:                                                                                                                                                                            
        .p2align 4,,15                                                                                                                                                              
        .globl  f1                                                                                                                                                                  
        .type   f1, @function                                                                                                                                                       
f1:                                                                                                                                                                                 
.LFB0:                                                                                                                                                                              
        .cfi_startproc                                                                                                                                                              
        addsd   .LC0(%rip), %xmm0                                                                                                                                                   
        mulsd   .LC1(%rip), %xmm0                                                                                                                                                   
        ret                                                                                                                                                                         
        .cfi_endproc                                                                                                                                                                
.LFE0:                                                                                                                                                                              
        .size   f1, .-f1                                                                                                                                                            
        .section        .text.unlikely                                                                                                                                              
.LCOLDE2:                                                                                                                                                                           
        .text                                                                                                                                                                       
.LHOTE2:                                                                                                                                                                            
        .section        .text.unlikely                                                                                                                                              
.LCOLDB3:                                                                                                                                                                           
        .text                                                                                                                                                                       
.LHOTB3:                                                                                                                                                                            
        .p2align 4,,15
        .globl  f2
        .type   f2, @function
f2:
.LFB1:
        .cfi_startproc
        addsd   .LC0(%rip), %xmm0
        mulsd   .LC1(%rip), %xmm0
        ret
        .cfi_endproc
.LFE1:
        .size   f2, .-f2
        .section        .text.unlikely
.LCOLDE3:
        .text
.LHOTE3:
        .section        .rodata.cst8,"aM",@progbits,8
        .align 8
.LC0:
        .long   0
        .long   -1069547520
        .align 8
.LC1:
        .long   1908874354
        .long   1071761180
        .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
        .section        .note.GNU-stack,"",@progbits
aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Задержки при переключении в режим ядра связаны с обращением к ядру, например, к видеодрайверу. И это так и в Linux, и в Windows.

Но я запомнил так, когда читал книгу. И ясно помню, что в линуксе рисовать объекты нужно из пользовательского пространства, и на это задержки, потому как рисовать системные вызовы линукса не умеют. А в windows рисуют системные вызовы, а это быстрее, чем пользовательское рисование.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от aureliano15

Признаю, был неправ.

-funsafe-math-optimizations

Никогда не использовал этот флаг, так как видел к каким ошибкам он тут приводит.

При -O3 -mfpmath=sse -march=bdver1 clang 4, clang 5, gcc 6.3, gcc 7.1 не выполняют таких оптимизаций.

  movsd   xmm0, qword ptr [rbp - 8] # xmm0 = mem[0],zero
  subsd   xmm0, xmm3
  mulsd   xmm0, xmm2
  divsd   xmm0, xmm1

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Есть ещё -ffast-math, в некоторых случаях его достаточно, чтобы компилятор решился перегруппировать операции.

i-rinat ★★★★★
()
Ответ на: комментарий от fsb4000

Не один компилятор не оптимизирует второй код до первого, при любом уровне оптимизации компилятора.

Потому что это РАЗНЫЙ код. Он будет давать, соответственно, разные результаты. Попробуй --ffast-math, и увидишь, как GCC или clang приведет длинный вариант к короткому

anonymous
()
Ответ на: комментарий от u0atgKIRznY5

Я же не пишу, что процессор переключается в графический режим, я пишу что из реального режима можно переключиться в графический.

Стоп, ты считаешь что реальный режим процессора и некий «графический режим» это сущности одной категории? При переключении из реального режима в графический, процессор теперь работает не в реальном режиме, а уже в каком-то «графическом» режиме, да?

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от u0atgKIRznY5

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

Умеют-умеют, ты вот например через системный вызов write в /dev/fb0 можешь рисовать запросто

SZT ★★★★★
()
Ответ на: комментарий от SZT

При переключении из реального режима в графический, процессор теперь работает не в реальном режиме, а уже в каком-то «графическом» режиме, да?

Нет. Процессор работает также в реальном режиме. Меняется только текстовый режим на графический.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от SZT

Умеют-умеют, ты вот например через системный вызов write в /dev/fb0 можешь рисовать запросто

А точно. Я даже помню как во фрейм буфере фильмы смотрел из консоли.

Ну а как тогда? Я вот уже начинаю сомневаться, но пока всё ещё уверен, и вот я опишу. За прорисовку окон и элементов на экране в линукс отвечает XWindowS, а она рисует в пользовательском пространстве, а пользовательским процессам выдаётся квант времени, и если нехватило времени, то потом из ядра в пользовательское надо переключаться, чтобы дорисовать. А в windows, если рисуют системные вызовы, то не завершив системный вызов, когда наступит очередь, это будет выполняться в режиме ядра, пока не нарисует. Как то так. А может и нет, ну я так представляю.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

FYI. Никакой графики в ядре винды нет. Графика в винде работает ровно по такому же принципу, что и в линаксе. В линаксе дисплейный сервер для отрисовки дергает OpenGL (Иксы напрямую дергали DRM), который реализован драйвером видеокарты или в проекте Mesa, который в свою очередь гоняет графику в DRM, который находится в ядре и реализуется драйвером видеокарты. Т.е. дисплейный сервер говорит видеодрайверу что нарисовать, а тот в свою очередь «рисует».

В винде абсолютно то же самое. Графика в винде работает по схожему принципу. Раньше использовался GDI, который представлял собой API для рисования. дергается он из юзерспейса, а сам API реализуется опять же драйвером видеокарты. В современных виндах весь интерфейс рисуется с помощью Direct3D, который реализован в драйвере, а дергается ВНЕЗАПНО из юзерспейса. Про подсистему винды можешь почитать тут.

При желании можешь запилить нативный X-сервер для шинды, который будет юзать OpenGL и GDI и всунуть его заместо штатного интерфейса.

Unicode4all ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

в линуксе рисовать объекты нужно из пользовательского пространства, и на это задержки, [skip] А в windows рисуют системные вызовы, а это быстрее, чем пользовательское рисование.

Вот тут желательно привести точную цитату из книги, а так же ссылку на книгу (желательно в Сети).

Потому что обычно всё наоборот: любой системный вызов стоит дороже, чем вызов в контексте вызывающего процесса. Поэтому по возможности рекомендуется не злоупотреблять системными вызовами.

aureliano15 ★★
()
Ответ на: комментарий от fsb4000

-funsafe-math-optimizations
Никогда не использовал этот флаг, так как видел к каким ошибкам он тут приводит.

Это уже проблема реализации gcc. Можно, например, использовать Intel C++ compiler, который гораздо лучше оптимизирует. Правда, компилирует только для Intel-совместимых платформ, проприетарен (хоть и бесплатен) и не совместим с gcc.

Хотя соглашусь с тем, что написать (f1/f2) вместо f1/f2 проще, чем полагаться на оптимизацию компилятора, которая может быть нормальной, может - глючной, а может вообще отсутствовать.

aureliano15 ★★
()
Ответ на: комментарий от anonymous

https://stackoverflow.com/questions/10274355/cycles-cost-for-l1-cache-hit-vs-...
Второй ответ говорит, что разница есть, а первый — что её нет

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

aureliano15 ★★
()
Ответ на: комментарий от u0atgKIRznY5

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

Это совсем другое. Если речь идёт о производительности вообще, то неважно, какому процессу сколько квантов выделяется. Можно увеличить длительность одного кванта, см., например, http://jurnal.org/articles/2007/inf11.html , тогда общая производительность может незначительно увеличиться за счёт уменьшения числа переключений в единицу времени, но время отклика каждого процесса на событие тоже увеличится, что может привести к субъективному ощущению «заторможенности» интерфейса при объективном увеличении производительности.

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

Если же надо на 100% (или почти на 100%) гарантировать выполнение заданной задачи на заданном железе за определённое время, то следует использовать ОСВР, коими ни Linux, ни Windows не являются.

aureliano15 ★★
()
Ответ на: комментарий от u0atgKIRznY5

Интересно, что тс ещё выдумает такого. Для меня все его посты как откровение))

anonymous
()
Ответ на: комментарий от u0atgKIRznY5

Процессор работает также в реальном режиме. Меняется только текстовый режим на графический.

Текстовый и графический режим это тоже такие режимы процессора, или может быть это режимы видеокарты, или чего-то еще?

SZT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Интересно, сколько надо одновременно тупых вопросов задать, чтобы сервер лора упал?

Тебя одного будет мало. Надо тебя как-нибудь копировать (например загрузить твое сознание в суперкомпьютер) и пустить на ЛОР кучу экземпляров тебя. Но это уже DDoS будет.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Тебя одного будет мало. Надо тебя как-нибудь копировать (например загрузить твое сознание в суперкомпьютер) и пустить на ЛОР кучу экземпляров тебя. Но это уже DDoS будет.

Ха ха.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от aureliano15

Это уже проблема реализации gcc. Можно, например, использовать Intel C++ compiler, который гораздо лучше оптимизирует.

Нет, не лучше. Если сравнивать компиляторы GCC, Clang, ICC, никакого однозначно лучшего компилятора там нет. Разные компиляторы в разных местах ошибаются, и разные вещи хорошо оптимизируют.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Текстовый и графический режим это тоже такие режимы процессора, или может быть это режимы видеокарты, или чего-то еще?

Кстати, я видел в книжке что графический режим работает тоже по адресу что и текстовый 0xb8000, только там цветов мало.

Наверное это bios vga, раз надо не 0x13 вызывать, а 0x10. Значит это режим видеокарты.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от SZT

Можно, например, использовать Intel C++ compiler, который гораздо лучше оптимизирует.

Нет, не лучше.

Ну, спорить не буду, т. к. сам не тестил, но много раз слышал, что лучше. Да и педивикия в очередной раз подтверждает, что

Главным достоинством компилятора являются выполняемые им высокоуровневые, а также целевые оптимизации под процессоры Intel.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Да и педивикия в очередной раз подтверждает, что

Главным достоинством компилятора являются выполняемые им высокоуровневые, а также целевые оптимизации под процессоры Intel.

Это они наверное скопипастили из рекламных материалов интел, или же кто-то из интела туда такую глупость написал(или кто-то перевел глупость, написаную кем-то), дабы пропиарить их проприетарный компилятор.

В общем и целом, явного лидера среди компиляторов нет. Интеловский компилятор вообще затачивался под всякий числодроб, да, там есть какие-то специальные оптимизации для этого. Но как компилятор «общего назначения» он явно не фаворит

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

https://blog.pgaddict.com/posts/postgresql-performance-with-gcc-clang-and-icc

Спасибо за ссылку.

surprisingly, icc gives the worst results here

Ну, конкретно по этому тесту автор сам пишет, что

The first observation is that once you start hitting the drives, compiler makes absolutely no measurable difference. That makes results from all the read-write tests (for all scales) uninteresting, as well as the read-only test on large dataset - for all these tests the I/O is the main bottleneck (and that's something the compiler can't really influence).

И разброс там от 98% до 106%, что легко объяснить разными случайностями (на плохом секторе диска задумался, какой-то другой читающий/пишущий процесс помешал и т. д.)

Но и в среднем по всем тестам icc хоть и не самый плохой, но явно не блещет, тут согласен.

aureliano15 ★★
()
Ответ на: комментарий от RazrFalcon

Нет описания зачем это нужно.

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

./bits A a
00000000000000000000000000010001
00000000000000000000000000110001

u0atgKIRznY5
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.