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

 WASM Phorum —› WASM.ZEN —› Запутался в loop'ах :(((

<< . 1 . 2 . 3 .

Посл.отвђт Сообщенiе


Дата: Июн 11, 2004 00:38:50

volodya
VC эти выделенные в стеке 32K будет каждый раз при вызове функции очищать. Хотя у других компиляторов в других ОС таких проблем может и нет 8) Возможно что в буфер стоит записывать только числа:
static char buf[el_num_max][??];

char format[??];

sprintf(format,"%u\\t%%s\\t%%s\\t%%s%%s\\t%%s\\t%%s\\t%%s%%s", mcid);

bindob *bo=bobject,*pi,*pj;
for(int i=0;i<el_num;i++)
{
  sprintf(buf,"\t%u\t%u",
      bo->mol_gi, bo->mol_tax);
  bo++;
}
for(i=0;i<el_num-1;i++)
{
   pj=pi+1;
   for(int j=i+1;j<el_num;j++)
   {
      fprintf(g_openfiles.matrix,format,
      pi->mol_type, pi->mol_db, pi->mol_acc, buf[i],
      pj->mol_type, pj->mol_db, pj->mol_acc, buf[j]);
      pj++;
   }
   pi++;
}


Дата: Июн 11, 2004 00:44:00

sprintf(format,"%u\\t%%s\\t%%s\\t%%s%%s\\t%%s\\t%%s\\t%%s%%s", mcid);
== GPF :))) Можем писать эксплоит :)

Ладно. Общую идею я ухватил. Наплюй. Пожалей свое время. Спасибо.


Дата: Июн 11, 2004 00:57:21

[ если заменить индекс на поинтерную арифметику получим явный прирост ]

В связи с этим вопрос: что лучше:
@@ add [ebx+esi],3 ;что-то делаем
   sub esi,4
   jne @@

или
@@ add [ebx+esi*4],3 ;что-то делаем
   dec esi
   jne @@


Дата: Июн 11, 2004 01:12:08

Для последних камней лучше sub.


Дата: Июн 11, 2004 01:35:27

На мой взляд примеры некорректные, Володя.
Во первых в for ты определяешь i как вынесенную переменную, а в do как константу что вынуждает компилятор в первом случае работать с памятью а во втором просто грузит константу в регистр.
Во вторых убрано внутренне условие, как бы априори мы должны признать мол do и for они и в Африке, чтобы не делалось внутри. Однако это не так - у тебя использовался выход по break из середины условия с использованием i и проверкой на неё. Здесь же ты эту внутренюю проверку убираешь.
Похоже на доказательство Незнайки "Это не облака а туман,
туман он густой как кисель, что я киселя не пил что-ли?"
Я ожидал что ты покажешь результат именно того кода который и приводил, или эмпирику или какую-то математику.

Вот и одним заявлением я готов согласится - что компилятор сделает из обоих кодов примерно одно и то же.

Потом "постулат" - это необходимое к принятию Неочевидное.
В отличии от аксиомы - необходимого к принятию очевидного,
так что то что ты сказал скорее аксиома :)
А вообще конечно код компилятора ужастный в обоих случаях :))
Но уже с незапамятных времён все for компиляторы переводят в while поэтому мне конечно было любопытно на чём ты основывал что while оптимальней.
Главное тут мы имеем блок кода на выполнение и вопрос где осуществлять проверку до выполнения блока или после.
Начиная с времени когда появилось предугадывания переходов было очевидно что процессору удобней будет на монотонных циклах проверку делать в конце блока. С тех пор формальные for компиляторы переделывали под логику while с проверкой на конце блока.


Дата: Июн 11, 2004 02:19:01

The Svin
[ Начиная с времени когда появилось предугадывания переходов было очевидно что процессору удобней будет на монотонных циклах проверку делать в конце блока. ]

А когда оно появилось? На х86 - сравнительно недавно. Преобразование в циклы с постусловием появилось раньше. И причина другая - потому что получается одна команда перехода на одну итерацию цикла.

[ Для последних камней лучше sub. ]

Угу. а если заменить dec esi >>> sub esi,1
тогда?


Дата: Июн 11, 2004 02:50:04

Причина не Другая, причина Ещё одна.
Суть исконной разницы была в том что при for одна итерация выполнялась в любом случае тогда как в while проверялась и первая. Сейчас эта разница нивилировалась.

если заменить dec esi на sub esi,1 то для новых камней это лучше. В остальном в двух примерах разницы нет. И там и там sib присутсвует так что ни на декодирование ни на выравнивание не должно влиять.
Вот в оригинальном варианте (c dec) второй случай мог в каких то вариантах оказаться быстрее на Старых (PI,PMMX), из-за того что код короче чем короче код, больше гарантий что весь цикл уместился бы в строчку кеша.
Но говорят на всяких не Intel овский процах маштабирование влияет в каких то случаях. Но мне другие (не Интеловские) модели как-то не были интерестны, так что лучше спросить у тех кто спец по всяким Атлонам и т.п.
Интел же ещё с DX 486 вводил в камень отдельным устройством параллельный сдвигатель и масштабирование никак не влияло.


Дата: Июн 11, 2004 03:31:00

The Svin
[ Причина не Другая, причина Ещё одна. ]

Нет, причина не Ещё Одна. Причина Первая и Основная ;). Оба варианта цикла предсказываются одинаково точно (как static так и dynamic механизмом). И это преобразование делается не для повышения точности предсказания.

[ Суть исконной разницы была в том что ... Сейчас эта разница нивилировалась. ]

Непонятно о чём речь. О конкретном клочке кода? Или за последнее десятилетие придуман новый способ программирования циклов? Во всяком случае то, что любая программа может быть переписана (причём автоматически) с использованием циклов только с постусловием, известно с незапамятных времён.


Дата: Июн 11, 2004 06:48:38

> Для последних камней лучше sub

Да, так пишет intel.
А если точнее, то:

The inc and dec instructions modify only a subset of the bits in the flag register. This creates a dependence on all previous writes of the flag register.

Но в примере captain cobalt используется флаг Z, а C не используется совсем, так что imho никаких зависимостей не будет - можно использовать inc. Хотя не знаю, PIV у меня нет что бы проверить.


Вот по поводу масштабирования не совсем понятно. Пишут, что для lea могут возникнуть замедления, но подробности не указаны.
Может быть и для сложных индексных операций тоже так бывает? Как-то туманно всё в книжке :(


Дата: Июн 11, 2004 12:01:40

volodya
sprintf(format,"%u\\t%%s\\t%%s\\t%%s%%s\\t%%s\\t%%s\\t%%s%%s", mcid);
== GPF :))) Можем писать эксплоит :)


Ну это только если под format мало памяти выделить 8)


Дата: Июн 11, 2004 15:49:03

Но в примере captain cobalt используется флаг Z, а C не используется совсем, так что imho никаких зависимостей не будет - можно использовать inc.
Да хоть бы PF флаг он использовал - быстрее будет с SUB.
Ты пытаешься спроецировать логику человеческую на логику компа. А сейчас попытайся разобраться по машинной логике - ты как разобрался что используется ZF а не CF?
Посмотрел на код?
А как процессору "посмотреть на код"?
Действие.
А как ему сделать чтобы он "посмотрел на код только раз за милльён операций"?
Вообще отсутсвует такой механизм. Он может предпологать в спекулятивном выполнении или предугадывании, но это не избавляет его от необходимости перепроверять.
С точки зрения камня самое экономичное - считать априори зависимым если используется dec или inc.
Но это не вредило на PI PMMX.
Просто в последних моделях спекулятивные запись, чтение, выполнение доведены до такой степени что это стало существенным.
Вторая скрытая вещь - о которой я могу только предпологать - это "предпологаемое" изменение микрокода на inc и dec.
Ощущение что он выполняются как sub с переходом на цепи по коррекции флага если реально это dec или inc. Это делает невозможным рассчёт по состоянию флагов "вперёд" пока не сделано выполнение этой образно говоря "ветки". И что просто вводит спекулятивное выполнение в состояние ожидания.

Оба варианта цикла предсказываются одинаково точно (как static так и dynamic механизмом).

Голословно и без доказательств.
Я скажу что не одинакого точно. Дальше перейдём "на сам дурак"?
Или перейдём к обсуждению механизмов предугадывания переходов и предвыборки?


Дата: Июн 11, 2004 18:54:29

Ну вы, Свин, и упрямец :)

Вот код. Реальный.
		for(;i< el_num; i++)
		{
			if (hash == bobject[i].hash)
			{
				bait_index = i;
				break;
			}
		}


.text:005D32D8 for_loop:                               ; CODE XREF: PrintSPOKE:loc_5D331Ej
.text:005D32D8                 mov     eax, [ebp+int_i]
.text:005D32DE                 add     eax, 1
.text:005D32E1                 mov     [ebp+int_i], eax
.text:005D32E7
.text:005D32E7 loc_5D32E7:                             ; CODE XREF: PrintSPOKE+56j
.text:005D32E7                 mov     eax, [ebp+int_i]
.text:005D32ED                 cmp     eax, [ebp+el_num]
.text:005D32F0                 jnb     short loc_5D3320
.text:005D32F2                 mov     eax, [ebp+int_i]
.text:005D32F8                 imul    eax, 138h
.text:005D32FE                 mov     ecx, [ebp+bobject]
.text:005D3301                 mov     edx, [ebp+hash]
.text:005D3307                 cmp     edx, [ecx+eax+134h]
.text:005D330E                 jnz     short loc_5D331E
.text:005D3310                 mov     eax, [ebp+int_i]
.text:005D3316                 mov     [ebp+bait_index], eax
.text:005D331C                 jmp     short loc_5D3320
.text:005D331E ; ---------------------------------------------------------------------- -----
.text:005D331E
.text:005D331E loc_5D331E:                             ; CODE XREF: PrintSPOKE+8Ej
.text:005D331E                 jmp     short for_loop

		i = el_num - 1; //опущено в ассемблерном листинге
		do
		{
			if (hash == bobject[i].hash)
			{
				bait_index = i;
				break;
			}
		}while(i--);

.text:0000C466 do_while:                               ; CODE XREF: _PrintSPOKE+B0j
.text:0000C466                 mov     eax, [ebp+int_i]
.text:0000C46C                 imul    eax, 138h
.text:0000C472                 mov     ecx, [ebp+bobject]
.text:0000C475                 mov     edx, [ebp+hash]
.text:0000C47B                 cmp     edx, [ecx+eax+134h]
.text:0000C482                 jnz     short loc_C492
.text:0000C484                 mov     eax, [ebp+int_i]
.text:0000C48A                 mov     [ebp+bait_index], eax
.text:0000C490                 jmp     short loc_C4B6
.text:0000C492 ; ---------------------------------------------------------------------- -----
.text:0000C492
.text:0000C492 loc_C492:                               ; CODE XREF: _PrintSPOKE+7Ej
.text:0000C492                 mov     eax, [ebp+int_i]
.text:0000C498                 mov     [ebp+tmp_i], eax
.text:0000C49E                 mov     ecx, [ebp+int_i]
.text:0000C4A4                 sub     ecx, 1
.text:0000C4A7                 mov     [ebp+int_i], ecx
.text:0000C4AD                 cmp     [ebp+tmp_i], 0
.text:0000C4B4                 jnz     short do_while


Дата: Июн 11, 2004 19:46:50

The Svin
[ А как процессору "посмотреть на код"? ]

А не работает ли здесь техника register renaming? Если значение используется, то надо ждать, пока оно будет готово; а если не используется - новое значение формируется с выделением ему нового регистра???

[ Дальше перейдём "на сам дурак"? ]
Sorry...

[ Или перейдём к обсуждению механизмов предугадывания переходов и предвыборки? ]
ОК.

Речь идет примерно о таких фрагментах кода:
Цикл с предусловием:
Начало_цикла: Код_проверки_условия
              je Выход_из_цикла

              Тело_цикла
              jmp Начало_цикла

Выход_из_цикла:

Цикл с постусловием:
Начало_цикла: Тело_цикла
              Код_проверки_условия
              jne Начало_цикла

Выход_из_цикла:

Вопрос заключается в том, почему "очевидно что процессору удобней будет на монотонных циклах проверку делать в конце блока" именно "Начиная с времени когда появилось предугадывания переходов"


Дата: Июн 11, 2004 22:02:46 · Поправил: S_T_A_S_

Вот это мне нравится. Кстати фраза меняется от мануала к мануалу:

Because of the complexity and subtlety of the Intel NetBurst micro-architecture, Chapter 2 of this document recommends what optimizations to use and what situations to avoid, and gives a sense of relative priority, but typically it does not absolutely quantify expected benefits and penalties. While this was more feasible with earlier in-order micro-architectures, this is no longer possible.

> "предпологаемое" изменение микрокода на inc и dec. Ощущение что он выполняются как sub с переходом на цепи по коррекции флага если реально это dec или inc

Да, я тоже предполагаю, что inc/dec декодируются на µops аналогичные add 1 / sub 1, только зависимость по флагам (которые не меняются inc/dec) в этом случае сохраняется.
Далее, я предпологаю, что процессор встречает µops соответствующие команде использующей ZF и начинает выполнение цикла с условием по состоянию этого флага.
Но, поскольку µops, использующих состояние CF, нет внутри этого цикла, то выполнение каких команд будет зависеть от замены sub на dec?
Думаю, если б действительно inc/dec были бы всегда медленнее, то PIV гораздо заметнее проигрывал бы P6 на "старом" коде.

Понятно мне одно - в мануалах интел часть технической информации заменяет общими фразами, порой рекламного характера.
Это наводит на мысль, что они навязывают стиль программирования, помогающий PIV выглядеть лучше чем другие :).

<< . 1 . 2 . 3 .


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