|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 16, 2004 21:08:34 Гм, на С пишется просто:
/* a must be >= b */
unsigned gcd(unsigned a, unsigned b)
{
while(b)
{
unsigned r = a % b;
a = b;
b = r;
}
return a;
}
Компилятор в режиме самой офуительной оптимизации выдал мне сие:
; _a$ = eax
; _b$ = ecx
; 8 : while(b)
test ecx, ecx
je SHORT $L8421
$L8420:
; 9 : {
; 10 : unsigned r = a % b;
xor edx, edx
div ecx
; 11 : a = b;
mov eax, ecx
test edx, edx
; 12 : b = r;
mov ecx, edx
jne SHORT $L8420
$L8421:
Как по мне, так в test edx, edx/jne SHORT $L8420 нужды нет. Можно было бы просто заменить это jmp. Плоды моих усилий вымучались в:
unsigned gcd(unsigned a, unsigned b)
{
unsigned r = 0;
__asm
{
mov eax, a
mov ecx, b
again:
test ecx, ecx
je SHORT end
xor edx, edx
div ecx
mov eax, ecx
mov ecx, edx
jmp SHORT again
end:
mov r, eax
}
return r;
}
Теперь, собственно, упражнение - максимально оптимизировать скорость. Как по мне, так уже больше некуда, но, может, я ошибаюсь? |
|
|
Дата: Авг 16, 2004 21:42:27 imho, вот так будет быстрее:
__declspec(naked)
unsigned int __fastcall gcd(unsigned int a, unsigned int b)
{
__asm
{
mov eax, ecx
l1:
cmp eax, edx
jae l2
xchg eax, edx
l2:
sub eax, edx
jnz l1
retn
}
} |
|
|
Дата: Авг 16, 2004 21:46:54 Может и быстрее, но алгоритм не работает :( И первая же инструкция мне не понравилась - ты перетираешь значение а! |
|
|
Дата: Авг 16, 2004 21:56:01 прошу прощения, не протестил :) Вот так у меня вроде работает:
__declspec(naked)
unsigned int __fastcall gcd(unsigned int a, unsigned int b)
{
__asm
{
xchg eax, ecx
l1:
cmp edx, eax
jae l2
xchg edx, eax
l2:
sub edx, eax
jnz l1
retn
}
} |
|
|
Дата: Авг 16, 2004 22:28:18 Проверил для 777 и 629, получается 37. Медоленные команды не используются. mov eax, a mov ecx, b @@: mov edx, eax sub eax, ecx jnc @b mov eax, ecx mov ecx, edx jnz @b mov r, eax |
|
|
Дата: Авг 16, 2004 22:51:26 S_T_A_S_ Два вопроса. 1) Чей алгоритм быстрее? Твой или green'a? 2) Что это за метка "@@"? И где метка "@b"? Ты пользуешься синтаксисом, которого я не знаю :( |
|
|
Дата: Авг 16, 2004 23:17:07 Сам алгоритм вроде одинаковый, заменили деление вычитанием. У меня не используется xchg, которая довольно медленна и не спаривается с другими командами. Одна команда проверки условия вместо 2х. Нет зависимости по данным, кроме как jnc сразу после sub (зато jnz должен быть предсказан одновременно с jnc). "@@" - это просто анонимная локальная метка, "@b" - значит переход на ближайшую "@@" назад (если "@f" - это вперёд). Я и забыл, что С регается на символы @ :-) |
|
|
Дата: Авг 16, 2004 23:22:37 volodya > 2) Что это за метка "@@"? И где метка "@b"? Ты пользуешься синтаксисом, которого я не знаю :( jmp @B или jmp @b - это прыжок назад на ближайшую метку @@: jmp @F или jmp @f - тоже самое, но вперед ;-) ЗЫ: нормальный ассемблерный синтаксис. |
|
|
Дата: Авг 16, 2004 23:23:33 Пока писал в оффлайне S_T_A_S_ меня уже опередил ;-) |
|
|
Дата: Авг 16, 2004 23:31:49 Все, понял. Всем спасибо :) |
|
|
Дата: Авг 16, 2004 23:48:34 S_T_A_S_ Твой алгоритм вычисляет наибольший общий делитель, но зацикливается после его нахождения. Вот так работает, правда две команды плюс: mov eax, 10557
mov ecx, 1530
@@: cmp eax,ecx
je short Exit
mov edx, eax
sub eax, ecx
jnc @B
mov eax, ecx
mov ecx, edx
jnz @B
Exit: |
|
|
Дата: Авг 17, 2004 00:01:46 cresta Мог бы и добавить, что ответ в eax :|> А от
@@: cmp eax,ecx
je short Exit
избавиться нельзя? Мне не нравится. |
|
|
Дата: Авг 17, 2004 00:15:41 Ой млин.. точно, спасибо :) косячный вариант запостил :( Правильно так: mov eax, a mov ecx, b @@: mov edx, eax sub eax, ecx ja @b mov eax, ecx mov ecx, edx jnz @b mov r, eax |
|
|
Дата: Авг 17, 2004 00:20:22 А алгоритм green'a для некоторых пар чисел выдаёт ошибочный результат. Я так понял, это зависит от содержимого edx. Если его обнулить перед циклом, то вообще зацикливается. Нельзя ли уточнить, что должно быть в регистре edx перед выполнением цикла? |
|
|
Дата: Авг 17, 2004 00:21:33 а вот так алгоритм S_T_A_S_ можно в С-код впаять: __declspec(naked)
unsigned int __fastcall gcd(unsigned int a, unsigned int b)
{
__asm
{
l:
mov eax, edx
sub edx, ecx
ja l
mov edx, ecx
mov ecx, eax
jnz l
ret
}
} |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.082 |