1. Заголовок или название темы должно быть информативным 2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE] 3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора. 5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM! 6. Проверяйте программы перед тем, как выложить их на форум!!
Я так понял, что каждое обращение к памяти, встречающееся в программе, долго и упорно обрабатывается системой на предмет залезания не туда, и если действительно было нарушение, вызывается обработчик исключения. Я сделал одну процедуру, у которой основной рабочий цикл (заполнении линии одинаковым, пока что, значением) выглядел так:
// заполнение регистра ecx длиной участка... jle @@; @: mov [eax], edx add eax, 4 // sub eax, 4 dec ecx; jnz @; @@:
Сделал замер скорости. Огорчился. Решил смеха ради добавить одну паразитную команду (она тут закомментирована). Получил резкое ускорение - то есть теперь данные стали выводиться в одно и то же место в памяти. Видимо система запомнила, куда в последний раз обращалась программа и не стала проверять обращение на корректность лишний раз. Как на самом деле обрабатываются обращения к памяти в винде? И можно ли использовать эту информацию для ускорения? Кстати, почему пара deс; jnz работает намного быстрее, чем loop, который специально предназначен для циклов?
procedure Delay2; begin asm mov ecx, $FFFFFFF @: dec ecx; jnz @; end; end;
begin
T := GetTickCount; while T = GetTickCount do; T := GetTickCount; Delay1; i := GetTickCount - T; WriteLn('loop: ', i);
T := GetTickCount; while T = GetTickCount do; T := GetTickCount; Delay2; i := GetTickCount - T; WriteLn('dec;jnz: ', i);
ReadLn; end.
> Во-первых, не факт, что на всех процессорах будет тот же эффект.
То есть чаще будет наоборот и поэтому имеет смысл сделать луп? Вот дельфийский компилятор тоже делает через вычитание, причём почему-то в качестве счётчика цикла выбран ebx. Ещё забавный эффект - если перед циклом записать что-то в стек и сразу извлечь обратно, то получится полуторакратное замедление.
> см. здесь
Ща почитаю.
> P.S. Перенести в Ассемблер?
Подтему с циклами - да. Но меня больше интересовала скорость заполнения фрагмента памяти, а она, мне кажется, связана с особенностями системы.
> А заменить dec ecx на sub ecx,1 не пробовал?
Если в исходном виде поменять - эффекта ноль. Усилил эффект, убрав всё тело цикла, заметил полуторакратное замедление суба по сравнению с деком. Луп же вышел ещё вдвое медленне суба.