Tempora mutantur, et nos mutamur in illis




НазваниеTempora mutantur, et nos mutamur in illis
страница7/9
Дата публикации09.03.2013
Размер1.08 Mb.
ТипДокументы
uchebilka.ru > Информатика > Документы
1   2   3   4   5   6   7   8   9
^

Шаг первый. Удаление printf


Конечно, полностью отказываться от вывода текущего состояния программы – глупо (пользователю ведь интересно знать сколько паролей уже перебрано, и потом надо ведь как-то контролировать машину – не зависла ли?), но можно ведь отображать не каждый перебираемый пароль, а скажем, каждый шестисотый, а еще лучше – каждый шеститысячный. При этом, накладные расходы на вызов printf значительно упадут, а то и вовсе приблизятся к нулю.

Давайте перепишем фрагмент, ответственный за вывод текущего состояния следующим образом:
static int x=0;

// вывод текущего состояния на терминал

if (++x>6666)

{

x = 0;

printf("Current pswd : %10s [%d%%]\r",&pswd[0],progress);

}

^ Листинг 12 Сокращение количества вызова функции printf
Батюшки мои! После перекомпиляции мы получаем скорость перебора свыше полутора миллионов паролей в секунду! То есть скорость программы возросла более, чем в пять раз! Программа выполняется так быстро, что "чувствительности" функции clock уже оказывается недостаточно для измерений и количество итераций приходится увеличивать раз в сто! И это, как мы убедимся в самом непосредственном будущем, еще отнюдь не предел быстродействия!


^

Шаг второй. Вынос strlen за тело цикла


Повторный запуск "обновленной" программы под профилировщиком показывает, что количество "горячих" точек в ней уменьшилось с 187 до 106. Конечно, это хорошо, но ведь горячие точки все еще есть! Кликнув в окне "View" расположенным в правом верхнем углу окна "Hot Spots" по радио – кнопке "Hotspots by function" (сортировать горячие точки по функциями), мы узнаем, что ~80% времени наша программа проводит в недрах функции Calculate CRC, затем с большим отрывом следует gen_pswd – ~12% и по ~3% делят функции Check CRK и do_pswd.

Ну это никуда не годится! Какая-то там задрипанная Calculate CRC без зазрения совести поглощает практически все быстродействие программы! Эх, вот бы еще узнать, какая именно часть функции в наибольшей степени влияет на производительность… И VTune позволяет это сделать!

Дважды кликнем по красному прямоугольнику, чтобы увеличить его на весь экран. Оказывается, внутри функции Calculate CRC насчитывается 18 горячих точек, три их которых наиболее горячи – ~30%, ~25% и ~10% соответственно (см. рис 0x003). Вот с первой из них мы и начнем. Дважды кликнем по самому высокому из прямоугольников и… VTune обижено пискнув сообщит, что "No source found for offset 0x69 into F:\.OPTIMIZE\src\Profil\pswd.exe. Proceed with disassembly only?" ("Исходные тексты не найдены. Продолжать с отображением только дизассемблерного текста?"). Действительно, поскольку программа откомпилирована без отладочной информации, то VTune не может знать, какой байт ассемблерного когда, какой строке соответствует, а компилятор не соглашается предоставить эту информацию в силу того, что в оптимизированной программе соответствие между исходным текстом и сгенерированным машинным кодов в общем-то не столь однозначно.

Конечно, можно профилировать и не оптимизированную программу, – но… какой в этом резон? Ведь это будет другая программа и с другими горячими точками! По любому, качественная оптимизация без знаний ассемблера невозможна, поэтому, прогнав все страхи прочь, смело нажмем кнопочку, "ОК", то есть "Да, мы соглашаемся работать без исходных текстов непосредственно с ассемблерным кодом".


^ Рисунок 8 0x003 Распределение температуры внутри функции Calculate CRC (снимок сделан с высоким разрешением)
VTune тут же тыкает нас носом в инструкцию REPNE SCANB. Не нужно быть провидцем, чтобы распознать в ней ядро функции strlen. Использовали ли мы strlen в исходном тексте программы? А то как же! Смотрим сюда:
int CalculateCRC(char *pswd)

{

int a;

int x = -1; // ошибка вычисления CRC

for (a = 0; a <= strlen(pswd); a++)

x += *(int *)((int)pswd + a);

return x;

}

Листинг 13 Вызов функции strlen в заголовке цикла привел к тому, что компилятор, не распознав в ней инварианта, не вынес ее из цикла, "благодаря" чему длина одной и той же строки стала подсчитываться на каждой итерации
Судя по всему бестолковый компилятор не вынес вызов strlen за тело цикла, хотя ее аргумент – переменная pswd не модифицировалась в цикле! Хорошо, если гора не идет к Магомету, пойдем навстречу компилятору и перепишем этот участок кода так:
int length;

length=strlen(pswd);

for (a = 0; a <= length; a++)

^ Листинг 14 Вынос функции strlen за пределы цикла
Перекомпилировав программу, мы с удовлетворением отметим, что теперь ее быстродействие возросло до трех с половиной миллионов паролей в секунду, т.е. практически в два с половиной раза больше, чем было в предыдущем случае.


1   2   3   4   5   6   7   8   9

Похожие:

Tempora mutantur, et nos mutamur in illis iconНовикова Михаила Петровича Gaudeamus tffttur Juvenes dum sunuts!...
Учебное пособие предназначено для студентов вузов и учащихся колледжей, гимназий, школ

Tempora mutantur, et nos mutamur in illis iconРеферат скачан с сайта allreferat wow ua
Возжелавшие ауспиций: «другие семьи» 7 Перспективы 8Раздел II. 10 “O tempora! O mores!” 10 Биология открытого брака 12 Моногамия...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<