Intel VTune Amplifier XE 2011 бета под строгия поглед на програмист
Реших да разгледам новия Intel VTune Amplifier XE 2011 бета и да напиша статия за случай на употреба. В процеса на писане обаче акцентът частично се измести от използването на усилвател към тестването му. Но това също е добре, надявам се разработчиците в Intel да вземат предвид желанията и да направят промени в следващата версия на инструмента. И като цяло ще критикувам себе си и всички.:)
Ще започна малко отдалеч, иначе ще има въпроси защо ми е бил необходим кодът, който трябваше да оптимизирам. Докато разработвам статичен анализатор на код за C ++, попадам на доста екзотични програмни фрагменти. Какво не измислят програмистите. И дори такива компилатори като Visual C ++ или Intel C ++ не, не, и те ще попаднат на следващата "кавичка".
В нашия статичен анализатор PVS-Studio има едно не много добро място, свързано с дефиницията на типа обект. Например има конструкция:
и е необходимо да "изчислим" типа B, за да разберем, че той не е нищо друго освен int. Разбира се, няма трудности с такива примери и всичко работи. Има обаче много объркващи ситуации. Позволете ми да ви дам пример за код, който показва къде започват да се появяват различни трудности:

Когато се опитаме да разберем типа на променливата X, ще разгледаме нейния тип в пространство от имена B и няма да го намерим там. Тогава ще видим, че трябва да търсим в пространство от имена C. И там също няма да го намерим. Сега трябва да разгледаме пространството от имена Б. Вечен цикъл. Разбира се, това е прост случай и с него също няма проблеми. Но добавете тук typedef, шаблони, наследени класове. Понякога се оказват изненадващо сложни неща, и то не нарочно. Това е особено очевидно в кода с шаблони.
За съжаление, инструментът PVS-Studio понякога влизаше във вечен цикъл на особено "успешни конструкции" и се самоубива след 5 минути, за да може да продължи обработката на други файлове. Много рядка ситуация, но неприятна. Грешките, разбира се, се коригират и коригират, но се откриват нови ситуации. Освен това не винаги е възможно да разберете какъв код има потребителят. Решено е да не се прекратява напълно работата на таймера на анализатора, а да се откаже получаването на типа на някакъв обект, ако възникне цикъл. По-добре да пропуснете една променлива, отколкото целия файл.
Ето една много интересна точка на несъвместимост между теорията и практиката. На теория трябва да се пише така, че да няма грешки. Можете дори да ни се скарате. Разработчиците на статичния анализатор, авторите на статии, как да пишат без грешки, но те самите не могат да направят правилното анализиране на типа променливи. Но се оказва, че не можем. И не само ние. Задачите, свързани със съставянето на C ++ код, са изключително трудни. И трябва да преминем от разсъждения за високото и красивото към създаване на петна за всеки случай.
Създаден е прост, но ефективен механизъм за спиране. Ако при получаване на типа на обекта получим указател към кодирания тип, с който вече сме работили преди, тогава спрете. Като начало беше създаден прост клас, който съдържа много указатели към std: set * m_pGuardPointers. Ако комплектът вече има указател, е време да спрете.
Не бях изненадан, когато изпълнението на програмата след такава промяна спадна многократно. Очаквах подобен ефект. Дори не измерих скоростта и затова е ясно, че тя е много бавна и причината е ясна. Обикновено дълбочината на типа "умозаключение" не е голяма и е просто глупаво да се използва тежка артилерия за такива случаи:
Веднага беше написан клас от следната форма (в съкратена форма):
Първо запазваме и търсим указатели в обикновен масив от 10 елемента и едва след това създаваме и започваме да използваме набора. Стана много по-добре, но всичко е няколко пъти по-бавно, отколкото без този механизъм.