· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Brain vs C compiler

<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . >>

Посл.отвђт Сообщен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;

<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.079