Обнаружение в run-time, или обнаружение во время авто-сборки на сервере? Во время авто-сборки, понятное дело, cpuid выдаст архитектуру сервера, который поддерживает и то, и другое. А если во время run-time, то скомпилированный файл будет больше размером.XVilka wrote:тогда может стоит обойтись без условной компиляции? Делать обнаружение SSE и CMOV через cpuid - и если не поддерживается - обходить оптимизированный код?
"Ночные" сборки KolibriOS
в рантайм. порядка 100 байт увеличение размера
yogev_ezra, системе сборки безразлично, сколько версий собирать, и добавить новую версию для сборки может любой с правами на коммит в репозиторий - для этого достаточно создать новую папку в data/ с файлом Makefile внутри и нужными настройками.
Я считаю, что не нужно делать разные сборки для разных процессоров, сборка должна быть универсальной. В любом случае от того, что сборка объявлена i586-совместимой, программы не изменятся, и код нужно будет переделывать на i586-совместимый; обычно - за исключением участков, критичных по скорости, которых мало; но все участки кода важны по размеру - можно просто сохранять код i586-совместимым, не используя новые инструкции. Там, где они действительно увеличивают скорость и это действительно важно, так что действительно нужны два варианта кода, лучше выбор между ними делать на стадии выполнения программы, а не при компиляции.
Я считаю, что не нужно делать разные сборки для разных процессоров, сборка должна быть универсальной. В любом случае от того, что сборка объявлена i586-совместимой, программы не изменятся, и код нужно будет переделывать на i586-совместимый; обычно - за исключением участков, критичных по скорости, которых мало; но все участки кода важны по размеру - можно просто сохранять код i586-совместимым, не используя новые инструкции. Там, где они действительно увеличивают скорость и это действительно важно, так что действительно нужны два варианта кода, лучше выбор между ними делать на стадии выполнения программы, а не при компиляции.
Сделаем мир лучше!
Большое спасибо за совет! Тогда подскажите, пожалуйста, как в FASM делать проверку на архитектуру?CleverMouse wrote:Я считаю, что не нужно делать разные сборки для разных процессоров, сборка должна быть универсальной. В любом случае от того, что сборка объявлена i586-совместимой, программы не изменятся, и код нужно будет переделывать на i586-совместимый; обычно - за исключением участков, критичных по скорости, которых мало; но все участки кода важны по размеру - можно просто сохранять код i586-совместимым, не используя новые инструкции. Там, где они действительно увеличивают скорость и это действительно важно, так что действительно нужны два варианта кода, лучше выбор между ними делать на стадии выполнения программы, а не при компиляции.
Я попробую внести это изменение в Snake - выглядит не очень сложно для меня.
Да не нужна там проверка на архитектуру, скорость некритична, так что достаточно версии для i586. Вставить макросы наподобие http://redmine.kolibrios.org/projects/k ... macros.inc (с) hidnplayr, и всё. Можно прямо в общий macros.inc.
Сделаем мир лучше!
Ну я для общего случая спросил - например, для Infinity скорость критична.CleverMouse wrote:Да не нужна там проверка на архитектуру, скорость некритична, так что достаточно версии для i586. Вставить макросы наподобие http://redmine.kolibrios.org/projects/k ... macros.inc (с) hidnplayr, и всё. Можно прямо в общий macros.inc.
Я правильно понял, что проверка выполняется командой "if __CPU_type eq p5" ?
Это проверка стадии компиляции - в качестве config.inc берётся programs/config.inc, в котором написано __CPU_type fix p5, и при компиляции с неизменённым programs/config.inc компилятор обработает код между if __CPU_type eq p5 ... end if; при отдельно взятой компиляции - не в автосборке - можно написать в config.inc что-нибудь другое, и тогда компилятор не будет обрабатывать код между if __CPU_type eq p5 ... end if.
Там, где скорость критична, желательно даже в универсальной сборке иметь оба варианта, для этого проверка стадии компиляции не годится.
Там, где скорость критична, желательно даже в универсальной сборке иметь оба варианта, для этого проверка стадии компиляции не годится.
Теперь мне более-менее ясно. Тогда я хочу добавить на SVN 2 авто-сборки: i586-eng и i586-rus, и попытаться сделать так, чтобы в этих авто-сборках всё компилировалось под i586, а в двух других авто-сборках поменять, чтобы всё компилировалось под i686. Таким образом, владельцы i686 смогут получить весь прирост производительности, какой только можно от всех программ, а пользователи i586 смогут запускать все приложения на своих компьютерах. У кого-то есть возражения против этого?CleverMouse wrote:Это проверка стадии компиляции - в качестве config.inc берётся programs/config.inc, в котором написано __CPU_type fix p5, и при компиляции с неизменённым programs/config.inc компилятор обработает код между if __CPU_type eq p5 ... end if; при отдельно взятой компиляции - не в автосборке - можно написать в config.inc что-нибудь другое, и тогда компилятор не будет обрабатывать код между if __CPU_type eq p5 ... end if.
Там, где скорость критична, желательно даже в универсальной сборке иметь оба варианта, для этого проверка стадии компиляции не годится.
yogev_ezra, я возражаю. При таком подходе скачавшие сборку i686 получат не только незаметную прибавку в скорости, но и заметное увеличение размера за счёт того, что код системного вызова с sysenter длиннее простого int 0x40, скачавшие сборку i586 не получат на новых процессорах скорости там, где это важно, на новых процессорах, хотя могли бы, а у поддерживающих всё это появится двойная головная боль от того, что придётся каждый раз уточнять, какая версия проверялась, - и вообще будет жуткая путаница, чреватая ошибками. Более того, никакие настройки сборки не сделают программы, использующие SSE2, работающими на i586.
Ну Вы уж прямо из крайности в крайность. Тогда подскажите, пожалуйста, как в отдельно взятой программе (например, Snake) сделать проверку на архитектуру в run-time? Macros by hidnplayr не делают этой проверки, они просто привязаны к config.inc . А я бы хотел увидеть именно код проверки архитектуры процессора.CleverMouse wrote:yogev_ezra, я возражаю. При таком подходе скачавшие сборку i686 получат не только незаметную прибавку в скорости, но и заметное увеличение размера за счёт того, что код системного вызова с sysenter длиннее простого int 0x40, скачавшие сборку i586 не получат на новых процессорах скорости там, где это важно, на новых процессорах, хотя могли бы, а у поддерживающих всё это появится двойная головная боль от того, что придётся каждый раз уточнять, какая версия проверялась, - и вообще будет жуткая путаница, чреватая ошибками. Более того, никакие настройки сборки не сделают программы, использующие SSE2, работающими на i586.
В начале работы программы нужно сделать
Теперь процедуру, в которой полезны инструкции cmovcc, нужно написать в двух вариантах - с этими инструкциями и без них - и вызывать косвенно
Это пример для CMOVcc, наличием SSE заведует бит 25, наличием SSE2 - бит 26 в edx, наличием SSE3 - бит 0 в ecx; проверка наличия, например, SSE2 имеет вид
Code: Select all
; get cpu info, class 1 - processor features
push 1
pop eax
cpuid
; set [speed_critical_proc] pointer to non-CMOVcc version
mov [speed_critical_proc], speed_critical_proc_i586
; test bit 15 of edx
test dx, dx
jns .cmovcc_not_supported
; if the bit is set, set [speed_critical_proc] pointer to CMOVcc version
mov [speed_critical_proc], speed_critical_proc_cmovcc
.cmovcc_not_supported:
Code: Select all
call [speed_critical_proc]
Code: Select all
; set [speed_critical_proc] pointer to non-SSE2 version
mov [speed_critical_proc], speed_critical_proc_i586
; test bit 26 of edx
bt edx, 26
jnc .sse2_not_supported
; SSE2 supported - set [speed_critical_proc] pointer to SSE2 version
mov [speed_critical_proc], speed_critical_proc_sse2
.sse2_not_supported:
Сделаем мир лучше!
yogev_ezra,
эти две cmovnz были добавлены из соображений компактности кода, о быстродействии _там_ я не думал, поэтому громоздкая проверка в рантайме, думаю, была бы неуместна. Я залил на svn изменённый под i586 вариант:
Исправлены только две строчки. Если ещё где-нибудь вылезет - сообщай.
CleverMouse,
предложение по файлу информации о сборке. Почему бы не использовать вывод команд вроде 'tree -s' или 'du -B 1'? На мой взгляд, они могут предоставить более детальную информацию в дополнение к текущему варианту.
эти две cmovnz были добавлены из соображений компактности кода, о быстродействии _там_ я не думал, поэтому громоздкая проверка в рантайме, думаю, была бы неуместна. Я залил на svn изменённый под i586 вариант:
Code: Select all
Index: snake.asm
===================================================================
--- snake.asm (revision 1860)
+++ snake.asm (revision 1861)
@@ -358,7 +358,9 @@
add eax, 5*2 ; skin width
mov esi, eax
test [proc_info.wnd_state], 0x01
- cmovnz eax, [proc_info.box.width]
+ jz @f
+ mov eax, [proc_info.box.width]
+ @@:
mov [window_width], eax
sub eax, [gw_mul_gs]
@@ -376,7 +378,9 @@
add eax, 5 ; skin height (bottom part)
mov edi, eax
test [proc_info.wnd_state], 0x01
- cmovnz eax, [proc_info.box.height]
+ jz @f
+ mov eax, [proc_info.box.height]
+ @@:
mov [window_height], eax
sub eax, [gh_mul_gs]
CleverMouse,
предложение по файлу информации о сборке. Почему бы не использовать вывод команд вроде 'tree -s' или 'du -B 1'? На мой взгляд, они могут предоставить более детальную информацию в дополнение к текущему варианту.
dunkaist, добавить детальную информацию о всех файлах легко, вопрос в том, нужно ли это.
Сделаем мир лучше!
yogev_ezra
Я соглашусь с CleverMouse о нецелесообразности сборки отличающейся от p5. Кроме увеличения размера приложения, можно получить несовместимость с процессорами, которые относятся 686-м, но не имеют поддержки sysenter или syscall.
В приложении разумеется можно действовать как угодно, но совместимость нужно сохранять. К тому же я не думаю, что Snake является показательным примером где требуется какой-либо особый прирост в скорости.
И еще мне кажется по прежнему имеется непонимание того что p5, p6 или к6, не являются синонимами подобными сборке 586 и 686 для *NIX систем. Поскольку в Колибри большинство программ на ассемблере, то меняется лишь метод обращения к API ядра - автоматического применения новых инструкций процессора от этого не происходит, как это сделано для компиляторов языков высокого уровня.
Таким образом от тупой замены int 0x40 на sysenter или syscall, мы не получим большого прироста, но получим головную боль от несовместимости.
З.Ы. Если уж мне лично нет особой веры, то читаем тему отсюда и далее. Там приводится мнение "эталона непогрешимости".
Я соглашусь с CleverMouse о нецелесообразности сборки отличающейся от p5. Кроме увеличения размера приложения, можно получить несовместимость с процессорами, которые относятся 686-м, но не имеют поддержки sysenter или syscall.
В приложении разумеется можно действовать как угодно, но совместимость нужно сохранять. К тому же я не думаю, что Snake является показательным примером где требуется какой-либо особый прирост в скорости.
И еще мне кажется по прежнему имеется непонимание того что p5, p6 или к6, не являются синонимами подобными сборке 586 и 686 для *NIX систем. Поскольку в Колибри большинство программ на ассемблере, то меняется лишь метод обращения к API ядра - автоматического применения новых инструкций процессора от этого не происходит, как это сделано для компиляторов языков высокого уровня.
Таким образом от тупой замены int 0x40 на sysenter или syscall, мы не получим большого прироста, но получим головную боль от несовместимости.
З.Ы. Если уж мне лично нет особой веры, то читаем тему отсюда и далее. Там приводится мнение "эталона непогрешимости".
Да, Вы правы, действительно - я думал, что это синонимы. С int 0x40 у меня, мягко говоря, нет никаких проблем, а твёрдо говоря, я вообще не понимаю, что это Поэтому 100% оставим, как естьMario wrote:И еще мне кажется по прежнему имеется непонимание того что p5, p6 или к6, не являются синонимами подобными сборке 586 и 686 для *NIX систем. Поскольку в Колибри большинство программ на ассемблере, то меняется лишь метод обращения к API ядра - автоматического применения новых инструкций процессора от этого не происходит, как это сделано для компиляторов языков высокого уровня.
Таким образом от тупой замены int 0x40 на sysenter или syscall, мы не получим большого прироста, но получим головную боль от несовместимости.
Проблема у меня только с командами и регистрами, появившимися начиная с процессора i686 (как то, cmov, xmm0). Для таких программ, как Infinity, быстродействие важно, поэтому при запуске на i686 эти команды логично оставить. Однако хотелось бы, чтобы они работали и на i586. Поэтому я и предложил делать 4 сборки вместо двух: по две на i586 и по две на i686. Мне это представляется более целесообразным, чем определение архитектуры в run-time, потому что скомпилированный код так будет короче.
Who is online
Users browsing this forum: No registered users and 26 guests