|
|
| Посл.отвђт | Сообщен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 выглядеть лучше чем другие :). |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.177 |