Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 21 • Страница 1 из 21  2  >
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Member
Статус: Не в сети
Регистрация: 26.06.2004
mein
Я не встречался со случаями когда break выглядит красивее. А ты Delphi знаешь? Скажи процедура XXX.close или XXX.free , это тоже аналоги Break?

А по поводу слишком длинного кода в условии: если время не критично, то в случае длинного кода можно использовать функции. Хотя я часто намеренно удлиняю код для ускорения (часто время выполнения очень критично), в общем когда цикл нужно ускорить я использую такую фишку:

Было:
for (100 раз например)
begin
xxx;
yyy;
...
end.

для ускорения:
for (50 раз)
begin
xxx;
yyy;
...
xxx;
yyy;
...
end;

При ипользовании такой фишки цикл может ускориться на 30-70%, можно и еще длиннее код делать, но как говориться все в меру! я больше 10 копий кода за одну итерацию еще ниразу не применял, так же как и goto, break.

Ой, вру, goto применял, когда писал на Fortran 77 :D но там деваться некуда!

Тему сделал отдельной. vor



Партнер
 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
Silver_Clash
Дельфи к сожалению не знаю(или к счастью :D ). Поэтому ничего сказать не могу.
Цитата:
Я не встречался со случаями когда break выглядит красивее

Да мне слово "break" просто нравится да и коротко, а как гласит известная поговорка ...
А из твоего примера я ничего не понял :) - ну ты и раставил эти операторы.


 

Member
Статус: Не в сети
Регистрация: 26.06.2004
Да не покарают меня модераторы за ОФФТОП но просветить людей надо.
mein
Объясняю: Как правил оператор цикла отнимает гораздо больше процессорного времени чем другие операторы.
Если число циклов сократить например в 2 раза за счет удвоения кода внутри цикла, прирост скорости должен быть существенным (30-70%). То есть получается число итераций сокращаем в двое, а внутри цикла два раза пишем одно и то-же, т.е. как-бы 2 итерации, если можно сказать старого образца, умещаются в одной итерации нового образца.

Уменьшать количество итерациё можно и более чем в 2 раза, но я более чем в 10 раз не применял, так как при дальнейшем уменьшении числа итераций прироста скорости я не замечал.


 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
Silver_Clash
Цитата:
Если число циклов сократить например в 2 раза за счет удвоения кода внутри цикла, прирост скорости должен быть существенным (30-70%). То есть получается число итераций сокращаем в двое, а внутри цикла два раза пишем одно и то-же, т.е. как-бы 2 итерации, если можно сказать старого образца, умещаются в одной итерации нового образца.

Идея понятна, но я думаю процент прироста скорости будет сильно падать с усложнением операций внутри цикла. Дело в лишних вызовах jmp, а может кривая реализация компилятора. Если первое, то два такта(а может и один) не столь критичны для сегодняшних камней.

Ray Adams
Цитата:
Использование break и continue считаю вполне нормальным

Вот и за меня заступились :dance:
Сёдня писал некое подобие switch(){} для PIC'а(микроконтроллер) на асме - вот это изврат: goto каждую вторую третью команду идут :) .


 

Member
Статус: Не в сети
Регистрация: 02.05.2004
Откуда: Tver
Все гораздо проще. Проверено практикой большим количеством неудачных программных проектов что мозг человека плохо разбирается с алгоритмом, который содержит много GOTO. Если без него не обойтись ( например текст сильно разбухает если эмулировать исключительные ситуации во вложенных циклах с помощью вспомогательных флагов и условий) то гораздо лучше быстрее и безопасней отправлять всех по GOTO. Важно не перестараться и помнить об "операторных скобках", например освобождать заказаную память или возвращать аппаратные биты в нужное состояние так как с GOTO поток команд не так очевиден.
По поводу "раскрытия цикла" не все так однозначно. Оптимизирующие компиляторы ( практически все ) часто сами используют этот трюк без вашего ведома. Припоминается знаменитейший в свое время Scaler Carmark'a тот что позволил добиться супер скорости Wolfenshtein 3D. Но например начитая с Dooom Кармарк сам его ограничил так как была потеря скорости из за слишком частой загрузки строк кеша команд в i486. А после Pentium Pro вообще невозможно предсказать как процессор будет переставлять команды. Это я к тому что сейчас все же лучше не забивать себе голову трюками и отдать это на откуп оптимизатору.


 

Member
Статус: Не в сети
Регистрация: 15.04.2004
Откуда: Москва
stacq
Silver_Clash
Разворот цикла дает перимущества только в том случае, если xxxx и yyyy являются операторами доступа к памяти.
Если это функции, или обращения к свойствам класса, то никакого прироста производительности не будет.
Проверено, для Cel Tualatin оптимальным является разворот цикла в 8 раз. И еще, для ускорения доступа к памяти старайся не создавать объекты размером больше размера страницы. И конечно, выравнивание.

_________________
Цель жизни - d20 по жизни...


 

Member
Статус: Не в сети
Регистрация: 15.04.2004
Откуда: Москва
S.Q.Lapp
break - это je (jg и т.д.) вперед, continue - je назад .
Предсказатель ветвления в PIII и выше работает по следующему алгоритму - "вперед практиски всегда, назад практически никогда".
Если continue случается меньше в 10% цикла, то на производительность не влияет.
Хуже break. Его лучше заменять на изменение счетчика на верхний предел (не пройдет в Delphi для цикла for, но потянет mov ebx,верхний предел) и continue.
Страшнее оптимизируется кусок типа
while i > 0 do try
....
finally
Dec(i)
end;
И еще. Delphi (5) счетчик цикла размещает в EBX, поэтому циклы получаются не очень оптимальные (счетчик в ECX и использование LOOP эффективнее).

_________________
Цель жизни - d20 по жизни...


 

несколько своих замечаний:
2 mein
конструкции вида while(1) IMHO аналогичны loopforever: {... } goto loopforever.
***
switch-case-brake, наверное, действительно, оправдывает слово break. и только тут. использовать его в циклах(aka while(1)) не стоит - можно обойтись
asize - размер в байтах
length - в битах ( ( length >> 3 ) <= asize )
char bfld[asize] - array itself
int bitfield :: operator == ( const bitfield& bf ) const
{
unsigned int i;
int res = 1; //true result
if ( length == bf.length )
//looks for unequal bytes and terminates
for ( i = 0; i < asize && res; i++ )
res = btfld[i] == bf.btfld[i]; //if one isfound
else
res = 0;
return res;
}
***
2 IliaV
конструкция switch-case-brake не позволяет делать сложные проверки.
(bc3.1 help: case <constant expression>: where constant expression must be an int...) для уменьшения громоздкости можно хорошо выровнять текст:
if () statment0;
else if () statement1;
else if () statement2;
....
else statementN;
***
при написании оптимизированного кода goto бывает очень полезен.

C другой стороны, goto-путаница возникает из-за того, что непонятно откуда перешло управление на метку...

PS: Поделитесь с общественностью, кто знает ссылки на серьезные работы на тему.
PSPS: маленькая очепятка в начале темы (испр.) "...не знаю куда."


 

Member
Статус: Не в сети
Регистрация: 04.01.2004
Откуда: 31
Avaddon
Пасиба за информацию :).

riskie
На счет break в switch - нет вопросов - нужно.
Цитата:
конструкция switch-case-brake не позволяет делать сложные проверки.

Как мне кажется, эта конструкция для этого не была предназначена изначально.

Кстати, раз уж мы ушли в сторону оптимизации... была у меня такая заморочка (в голове :)). Как-то писал программку и был такой код (не помню уже зачем)
Код:
int i;
...
if (i == 1)
  i = 2;
else
  i = 1;


Т.е. если 1, то 2, и наоборот.
Ну очень мне не понравилось - вроде всего одно действие. Захотелось покрасивее, что-то вроде
Код:
bool b;
...
b = !b;


В итоге заменил на
Код:
i = i ^ 3;

Причем числа могут быть произвольными, а не только 1 и 2.
Красота. Читабельность, правда, нулевая. Зато скорость :).

Кстати... можно ветку создать посвященную оптимизации кода (не таким извращениям как я написал, а реальным), или эту переименовать.


 

Member
Статус: Не в сети
Регистрация: 30.04.2004
Откуда: [Omsk Team]
S.Q.Lapp
Код:
if (i == 1)
  i = 2;
else
  i = 1;

а как насчет
Код:
(i==1)?2:1

_________________
forum.omskteam.ru- Все о керамограните


 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
Dilon
Твой вариант понятен и мамонту - это плюс, но это же тот же самый иф-элс(просто запись укороченаяя), а после компила получится нечто большое и неоптимизированное всё равно.
S.Q.Lapp
Цитата:
В итоге заменил на
Код:
i = i ^ 3;
Причем числа могут быть произвольными, а не только 1 и 2.
Красота. Читабельность, правда, нулевая. Зато скорость .

Вот это действительно красиво. Только я даже не знаю что за оператор "^". С ходу придумал два своих варианта:
Код:
i=(!(--i))+1;

или
Код:
i=(i&1)+1;

Реализация на асме этого дела не должна быть большой. Последнего например:
Код:
and ax,1
inc ax
. Выполнятся должно быстро по идее. Но читабельность опять же не каждый найдёт.


 

...
В итоге заменил на
Код:
i = i ^ 3;

Причем числа могут быть произвольными, а не только 1 и 2.
Красота. Читабельность, правда, нулевая. Зато скорость :).
...
я бы записал так
i ^= 3;


 

Member
Статус: Не в сети
Регистрация: 04.01.2004
Откуда: 31
riskie
:) исчо короче
Кстати, посмотрел дизасмом - всего одна строчка
Код:
xor bla-bla-bla, 3

Хотя чего ещё ожидать?
(для mein: ^ - исключающее "или" - xor).


 

Member
Статус: Не в сети
Регистрация: 15.04.2004
Откуда: Москва
Dilon
А при компиляции получится одно и то же :)
ТОлько второй вариант читается сложнее. Ну это и ежу понятно, что С/С++ и Perl - write-only languages

_________________
Цель жизни - d20 по жизни...


 

Member
Статус: Не в сети
Регистрация: 30.04.2004
Откуда: [Omsk Team]
ну я только на читабельность претендовал :)
10 или 5 тактов затратит процессор мне не важно ;)

_________________
forum.omskteam.ru- Все о керамограните


 

Member
Статус: Не в сети
Регистрация: 14.03.2004
Откуда: Москва
Если писать быстрый код, то тогда добро пожаловать на ASM

_________________
ФИЗТЕХ- рулез, ФАКИ - сила, Кванты тоже хорошо


 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
Вот ломал голову(больную :) ) пол дня - так и не решил. В общем нужно менять(toggle) один бит в слове не трогая остальные биты. Я щас делаю деревянно:
если нужный бит=1 то очищаем его иначе ставим 1. На асме(для моего микроконтроллера) выглядит так:
Код:
LDP      #PBDATDIR>>7  ; переход на страницу
BIT      PBDATDIR,BIT5  ; типа test
LACL     PBDATDIR  ;  загружаем в аккумулятор регистр
BCND     _NULL_BIT_,TC  ; проверяем результат тестирования бита
OR       #0000000000010000b  ; выставляем нужный бит 1
SACL     PBDATDIR  ; загоняем обратно в регистр
B        _EXIT_TEST_  ; убегаем отседова
_NULL_BIT_  ;
AND      #1111111111101111b  ;
SACL     PBDATDIR  ;...
_EXIT_TEST_


Так вот эта вся байда меня не очень устраивает(длинно, некрасиво и с прыжками) - хотел чёто пооптимизированнее придумать да ничё не пришло в голову. Есть в наличии такие команды: AND,OR,XOR,ROL,SFL. Может есть какойто линейный алгоритмик в несколько логических команд делающий это дело?


 

Member
Статус: Не в сети
Регистрация: 11.11.2004
Откуда: Челябинск
mein Если сделать XOR операнда с числом, у которого нужный бит = 1, то этот бит операнда проинвертируется. Вроде так всегда было... :?:
А что за микроконтроллер?

Вроде так, хотя я этот ассемблер не знаю
LDP #PBDATDIR>>7 ; переход на страницу
LACL PBDATDIR ; загружаем в аккумулятор регистр
XOR #0000000000010000b ; инвертируем нужный бит
SACL PBDATDIR ; загоняем обратно в регистр

_________________
пишу я программу... и вдруг на клавиатуру выползает bug, буквально


 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
Rius
Не, не получится: например если в нулевом бите был ноль то после операции получим единицу, что не гуд. Вот если если бы сначала загнать в аккумул-р регистр, потом его инвертнуть, потом выставить единицу в нужном месте, то тогда xor по идее должен сработать. Но как инвертнуть...

зы: сигнальный миrроrонтроллер серии ТМS320xxx


 

Member
Статус: Не в сети
Регистрация: 11.11.2004
Откуда: Челябинск
mein Два нуля после XOR'а не дадут единицу. См. таблицы истинности.
Вот например в симуляторе MPLAB 6.62 (для PIC):
Цитата:
unsigned char x = 0b01101010;
unsigned char y = 0b00001000;
x = x^y;
В результате наблюдаем в Watch'ах:
Цитата:
x = 01100010
y = 00001000

Выполняем ещё раз команду
Цитата:
x = x^y;
и получаем
Цитата:
x = 01101010
y = 00001000


P.S. кстати, у Z80 самый быстрый способ очистить аккумулятор (сделать=0) -
Код:
xor a
Т.е. a = a xor a

0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

_________________
пишу я программу... и вдруг на клавиатуру выползает bug, буквально


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 21 • Страница 1 из 21  2  >
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan