|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 29, 2003 14:19:16 Вот ещё лишнюю инструкцию нашёл, можно без inc ebx add eax,1 ;0 или eax +1 sbb ebx,ebx ;-1 или 0 and edx,ebx ;edx или 0 ;inc ebx ;1 или 0 ;sub eax,ebx ;eax или eax - 1 add eax,ebx ;eax или eax - 1 add edx,1 sbb ebx,ebx not ebx add edx,ebx xor eax,edx |
|
|
Дата: Авг 29, 2003 14:28:05 Нет, нет, в случае если и a и b = -1 не работает, должно 0 быть равно. А получается а+1 в случае -1 будет 0 и еще прибавим -1 (в ebx), получим опять -1 в eax. |
|
|
Дата: Авг 29, 2003 14:55:14 Тогда здесь можно байт сократить: add edx,1 ;0 или edx+1 sbb ebx,ebx ;-1 или 0 not ebx ;0 или -1 add edx,ebx ;edx+0 или edx-1 not ebx на inc ebx и теперь add edx,ebx на sub edx,ebx т.е. как ты делал в первой части. на данный момент получается что-то вроде add eax,1 ;0 или eax +1 sbb ebx,ebx ;-1 или 0 and edx,ebx ;edx или 0 inc ebx ;0 или 1 sub eax,ebx ;eax или eax - 1 add edx,1 ;0 или edx+1 sbb ebx,ebx ;-1 или 0 ;not ebx ;0 или -1 inc ebx ;0 или 1 ;add edx,ebx ;edx+0 или edx-1 sub edx,ebx ;edx-0 или edx-1 xor eax,edx ; результат |
|
|
Дата: Авг 29, 2003 15:10:49 Ага, так все нормально. Теперь-то уж точно больше не вытянуть - 4 такта и 20 байт. В принципе, размер не так важен. Спасибо. Можно теперь смело резюмировать, что сишный компилятор мы победили (по скорости) :)) |
|
|
Дата: Авг 29, 2003 15:12:40 Теперь-то уж точно больше не вытянуть Кончай ты эти точки ставить :) |
|
|
Дата: Сен 2, 2003 22:50:06 Страшные ассемблерные люди, masquer, поправь меня, программера на С, который балуется асмом. Что мешает превратить: if(a == -1) a = b; if(a == -1) a = 0; в вот это: if( a == -1) (b == -1)?(a = 0):(a = b); и получить в результате вот это, а не обвинять компилятор: ; 12 : if( a == -1) 0000c 83 f8 ff cmp eax, -1 0000f 75 0f jne SHORT $L1458 ; 13 : (b == -1)?(a = 0):(a = b); 00011 8b 44 24 00 mov eax, DWORD PTR _b$[esp+4] 00015 33 c9 xor ecx, ecx 00017 83 f8 ff cmp eax, -1 0001a 0f 94 c1 sete cl 0001d 49 dec ecx 0001e 23 c1 and eax, ecx |
|
|
Дата: Сен 3, 2003 00:55:02 На С красивее будет if (a == -1) a = (b == -1)? 0 : b; и соответствующий код генерируемый компилятором cmp eax, -1 jne exit mov eax, b sub eax, -1 neg eax sbb eax, eax and eax, b exit: |
|
|
Дата: Сен 3, 2003 01:01:40 Fixer Да вот то-то и оно! Пусть сначала условие корректно компилятору ставят! А то придумали код, который изначально криво выглядит, а потом давай его на асме до ума доводить, ругая при этом компилятор. Я набросал код впопыхах, грубо, ты его приукрасил, компилятор, ессно, еще больше улучшил качество кода. |
|
|
Дата: Сен 3, 2003 02:22:41 Оба результаты бранчевые. Объяснять последствия думаю не нужно. |
|
|
Дата: Сен 3, 2003 02:27:58 · Поправил: volodya с прямым утверждением согласен. Но код стал значительно красивее, чем в первоначальном варианте от masquer. Может быть, можно еще улучшить результат. Надо подумать. Просто лень церебральным сексом заниматься... |
|
|
Дата: Сен 3, 2003 03:41:20 Дык это красота то в сишном коде, в реалиях просто безбранчевая проверка первого условия здесь заменена бранчевой. Если её оставить, то конечно можно короче cmp eax,-1 jne exit mov eax,b add eax,1 cmc sbb eax,0 тут сишн-ассемблерный листинг трудно оценивать в смысле размера. непонятно как адресуется b. но всё равно будет короче. |
|
|
Дата: Сен 3, 2003 04:04:01 Если размер волнует а не бранчи, то вообще очень коротко (и в мнемониках и в реальных байтах) cmp eax,-1 ;3b jne exit ;2b mov eax,b ;2b + возможный sib и 1 или 4 дисплейсмент. inc eax ;1b je exit ;2b dec eax ;1b exit: итого 11 байт + от 0 до 5и хвост адресации b раскладка компиляторского варианта: cmp eax, -1 ;3b jne exit ;2b mov eax, b ;2b + возможный sib и 1 или 4дисплейсмент. sub eax, -1 ;3b neg eax ;2b sbb eax, eax ;2b and eax, b ;2b + возможный sib и 1 или 4дисплейсмент. exit: итого 16 байт + 2(от 0 до 5) т.е минимальная разница 5 байт. Максимальная 10байт. В зависимости от адресации b. |
|
|
Дата: Сен 3, 2003 04:25:44 The Svin Оки-доки. Никто и не спорил с тем, что вручную вылизанный ассемблерный код будет хуже. Он всегда будет лучше. Фокус-покус в том, что HLL-программист, пишущий на компилируемых языках, но разбирающийся в асме, всегда придумает как облегчить жизнь компилятору для производства более быстрого кода, как то, сравнение с нулем где можно и где не можно, развертка циклов, выравнивание данных, инвертирование циклов, использование указателей вместо индексов массива, использование условного оператора вместо if и т.д., и т.п. |
|
|
Дата: Сен 3, 2003 06:59:07 Согласен. |
|
|
Дата: Сен 3, 2003 07:58:18 Фокус-покус в том, что HLL-программист, пишущий на компилируемых языках, но разбирающийся в асме, всегда придумает как облегчить жизнь компилятору для производства более быстрого кода, как то, сравнение с нулем где можно и где не можно, развертка циклов, выравнивание данных, инвертирование циклов, использование указателей вместо индексов массива, использование условного оператора вместо if и т.д., и т.п. Обычно да, но иногда вроде бы очевидные оптимизации снижают скорость работы (видимо, программерские оптимизации иногда мешают компиляторским оптимизациям??). Вот случай из практики. Ниже приведён примерный фрагмент кода в трёх вариантах. Из них самым быстрым оказался первый!!! TBlock Blocks[]; DWORD Count; ... for (a=0;a<Count;a++) if (Blocks[a].SomeField==Value) break; for (a=0;;a++) //в данной задаче условие было избыточным if (Blocks[a].SomeField==Value) break; TBlock* pBlock=Blocks+Count; for (;--pBlock>=Blocks;) if (pBlock->SomeField==Value) break; |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.079 |