|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Мар 30, 2004 20:59:15 Asterix Тренеруйся, тренеруйся :) Я толдычу уже несколько лет: книжки должны учить на 95 процентов как создавать мат. модели и писать алгоритмы и только на 5% давать описания прерываний и прочее. Это алгоритм для первоклассника. Что ты 5 минут посидел и всё что ли? Тренеруйся. Имей ввиду - операнд терабайт. Т.е. если даже в строке у тебя нет стольки разрядов - старшие, оставшиеся заполнить нулями (если у тебя безнаковые) А то ишь! Свели всё программирование к поиску по Гуглам и описанию чужих функций :) Арбайтен :)) |
|
|
Дата: Мар 30, 2004 21:15:23 · Поправил: Asterix [ The Svin: Имей ввиду - операнд терабайт. Т.е. если даже в строке у тебя нет стольки разрядов - старшие, оставшиеся заполнить нулями (если у тебя безнаковые)] Нужно просто заранее обнулить переменную чтоб не добивать потом нулями. Кажется нужно так, но сколько же кода это всё потребовало, мне кажется что мой первоначальный вариант гораздо проще ;-) invoke lstrlen, OFFSET szSrc
lea esi, [szSrc+eax-1]
push eax
shr eax, 1
sbb eax, eax
test eax, eax
pop eax
jz @F
inc eax
@@:
shr eax, 1
mov edx, eax
lea edi, sDest
push edi
xor eax, eax
mov ecx, 5
cld
rep stosw
xor ebx, ebx
adc ecx, 2
pop edi
std
@@:
lodsb
shl ebx, 8
xor eax, 030h
or ebx, eax
loop @B
xchg eax, ebx
xchg ah, al
aad_16
mov BYTE PTR [edi], al
xor ebx, ebx
xor eax, eax
adc ecx, 2
inc edi
dec edx
jnz @B
@@:
fbld sDest
Поправил.. Еще немного соптимизировал :-) |
|
|
Дата: Мар 30, 2004 23:22:56 Asterix Загляни на вторую страницу раздела посвященного алгоритмам, там есть темы Int_to_Str и Str_to_Int. fbld инструкция доволно тормозная(у меня 80 тактов выполняется). Думаю лучше перевести в Int, а потом fild использовать. |
|
|
Дата: Мар 31, 2004 00:16:42 Black_mirror до квинтиллионов что ли? |
|
|
Дата: Мар 31, 2004 00:44:29 · Поправил: Asterix . |
|
|
Дата: Мар 31, 2004 08:53:11 Здравый смысл подсказывает, что десятичное представление чисел нужно лишь при взаимодействии с человеком. Поскольку большинство людей неспособны генерировать\воспринимать десятичные числа со скоростью мегабайтов в секунду, то перевод это не та операция, которую нужно оптимизировать по скорости. А раз так, то ее нужно оптимизировать по размеру - использовать BCD. isn't it ? |
|
|
Дата: Мар 31, 2004 10:48:55 > Здравый смысл подсказывает, что десятичное представление чисел нужно лишь при взаимодействии с человеком. В данном случае как раз нет ;-) |
|
|
Дата: Мар 31, 2004 13:07:10 Ещё пока вообще никто ни показал ни доказал, что тут будет быстрее. Никаких сравнений я не видел. fbld медленная но при использовании её вообще отпадает надобность что то умножать и прибавлять. Поскольку знаковый QWORD может быть использован с fbld до 18и знаков в десятичной, получается что исползование fbld избавляет от до 18(m+a) где m и a такты синхронизации на умножение и сложение + контрольные такты. Кроме того одним простым циклом 64итное число не преобразовать, нужно будет делить на разрядные фракции, делать раздельное преобразование, один из результатов её раз умножать и потом складывать. Но при fbld возникает необходимость в преобразовании в BCD террабайт. Это преобразование можно делать очень по разному и есть возможность сделать довольно быстро. Пока же не доказательств математических ни тестов эмпирических тут не было приведено. Так, что рановато приклеивать тут ярлычки на тему "что быстрее". Лучше давайте-ка потренеруемся раскладывать задачку на составляющие и находить модельки решения. Одна задачка: как быстро перевести террабайт BCD ASCIIZ строку представляющую символьную запись десятичного числа. Другая задачка - такую же строку (содержащую <= 18 символов) перевести в QWORD. Asterix, молодец что пытаешься. |
|
|
Дата: Мар 31, 2004 15:27:54 · Поправил: Asterix Тут будет ещё проще, только я не понял fbstp оно не учитывает дробную часть fbstp sSrc
lea esi, sSrc
lea edi, [sBuffer+18]
mov ecx, 9
cld
@@:
lodsb
aam_16
xchg ah, al
or ax, 03030h
dec edi
dec edi
mov WORD PTR [edi], ax
loop @B
mov ecx, 18
mov al, '0'
repe scasb
dec edi |
|
|
Дата: Мар 31, 2004 17:19:15 Я имел ввиду перевод ASCIIZ десятичной строки в QWORD а не BCD в ASCIIZ строку. Повторюсь ещё раз. Предложено две альтернативы 1. Целочисленно перевести ASCIIZ в QWORD и сделать fild fstp 2. Перевести ASCIIZ в BCD и сделать fbld fstp. Главная нагрузка соответсвенно в первой части ложится на код преобразующий до 18и разрядов десятичную строку в QWORD, а во втором случае конвертирование в BCD. То что ты написал (в последнем посте), это конвертирование из BCD в ASCIIZ. А вот что никто пока не предложил (кроме твоего самого первого варианта с использыванием FPU) так это перевода из ASCIIZ (до квинтиллионов) в QWORD. Black_mirror утверждает, что так будет быстрее. Однако никто ещё не показал насколько быстрее будет перевести строку содержащую до 18и символов в 64х разрядное целое. (С использование FPU это стопудово будет медленнее, достаточно умножить длительности (fimul mem + fiadd mem) на 18 чтобы понять это). |
|
|
Дата: Мар 31, 2004 20:25:35 The Svin stof1:;(str +4)
mov esi,[esp+4]
xor edi,edi
xor ecx,ecx
xor eax,eax
.loop:
add ecx,ecx
adc edi,edi
mov ebx,ecx
add ecx,ecx
mov edx,edi
adc edi,edi
add ecx,ecx
adc edi,edi
add ecx,ebx
adc edi,edx
lodsb
sub al,'0'
add ecx,eax
adc edi,0
cmp al,9
jbe .loop
push edi
push ecx
fild qword [esp]
add esp,8
ret 4
stof2:;(str +4)
mov esi,[esp+4]
fld [.ten]
fldz
xor eax,eax
push eax
.loop:
fmul st0,st1
fiadd dword [esp]
.load:
lodsb
sub al,'0'
cmp al,9
mov [esp],eax
jbe .loop
fstp st1
add esp,4
ret 4
.ten dd 10.0
Для процессора AthXP1900+(частота системной шины 133, память DDR333, частота процессора 1600), при переводе 18-значного числа, получены следующие результаты: stof1 - выполняется 182 такта(вместе с вызовом функции) stof2 - выполняется 191 такт (первоначальный вариант stof1 с двумя целочисленными умножениями в цикле выполнялся 200 тактов) Код Asterix'а с fbld(с этой страницы) у меня выполняется где-то 450 тактов(виду отсутствия, lstrlen был заменен на mov eax,18). А самый первый вариант(без fbld) - 241 такт. |
|
|
Дата: Мар 31, 2004 21:26:49 · Поправил: Asterix Black_mirror Спасибо за код и выкладки. А что можешь сказать по поводу обратной операции(float2string), что здесь лучше использовать? Зы: не такой уж медленный, оказывается, мой первый вариант ;-) |
|
|
Дата: Мар 31, 2004 23:24:06 Код появился, хорошо, это радует :) Только почему то без комметариев. Почему у нас по поводу всякой политики MS всегда килограмм слов а на объяснение арифметики мы их жалеем? Black_mirror Обрати внимание на это кусок в первой процедуре: 0. lodsb 1. sub al,'0' 2. add ecx,eax 3. adc edi,0 4. cmp al,9 5. jbe .loop 6. push edi 7. push ecx fild qword [esp] lodsb на шаге 0 загружает очередной символ строки. А проверяется не является ли он нулём лишь на 5ом. При этом если это последний символ (0) то а) на шаге 1 из него сделают D0 б) на шагах 2 и 3 D0 благополучно прибавится к 64 битному числу в) и на шаге 6, 7 это число больше нужного на D0 благополучно передаётся на загрузку. Так, что условия выхода я бы поменял. Либо нужно загрузить -D0h в есx edi начально. Кроме того получается лишняя итерация. Кроме того заменил бы lodsb на mov al,[esi] add esi,1 если речь идёт о скорости. Результат с fbld медленный по простой причине, мы пока не видим качественного перевода в BCD. По поводу первой процедуры есть простое замечание: Используем тот факт, что если в al у нас символ строки, то зная что она определена на множестве [30h,31h...39h,0] при вычитании из него 30h CF установится только в том случае, если это 0. Таким образом переводя символ в бинарное значение очередного десятичного разряда мы можем одновременно и определить не является ли это концом строки. Из этого следует что преобразование должно быть в конце (последней командой перед управляющей) а прибавление уже в следующей итерации. |
|
|
Дата: Мар 31, 2004 23:49:02 Что-то я не пойму, что с точностью, протестил разные варианты и получил такие результаты: Исходная строка - "31029294951234567" 3.1029294951234585600e+17 by Black_mirror вариант 1 3.1029294951234565120e+16 <-первый вариант (aaa заменил на and eax, 00000000Fh) 3.1029294951234565120e+16 <-BCD |
|
|
Дата: Мар 31, 2004 23:58:20 · Поправил: Black_mirror The Svin Баг исправил, и это сэкономило еще 6 тактов: stoi64:;(str +4)
mov esi,[esp+4]
xor edi,edi
xor ecx,ecx
xor eax,eax
.loop:
add ecx,ecx
adc edi,edi
mov ebx,ecx
add ecx,ecx
mov edx,edi
adc edi,edi
add ecx,ecx
adc edi,edi
add ecx,ebx
adc edi,edx
add ecx,eax
adc edi,0
mov al,[esi]
sub al,'0'
inc esi
cmp al,9;проверяется цифра это или нет
jbe .loop;поэтому здесь такой переход
push edi
push ecx
fild qword [esp]
add esp,8
ret 4 |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.088 |