ответ на задание 1 (1124142)
Текст из файла
Василенко Анатолий421 группаТестирование под Linux:realusersysrealusersys1. Характеристики системы:1. Процессор - Core 2 Duo - 2 ядра по 2,4 GHz (используется конечно же одно (за исключением того,что некоторые вызовы оси могут быть паралельны))2. Linux x64 - установлен на вирутальную машину из под vmware3. Процессор поддерживает Intel VT (Virutalization Technology)2. Замеры при помощи утилиты time:1. Было сделано 10 замеров:0m1.028s 0m1.089s 0m1.048s 0m1.092s 0m0.942s 0m1.047s 0m1.139s 0m0.986s 0m1.078s 0m0.992s0m0.664s 0m0.612s 0m0.608s 0m0.608s 0m0.588s 0m0.604s 0m0.580s 0m0.508s 0m0.620s 0m0.612s0m0.360s 0m0.472s 0m0.432s 0m0.484s 0m0.348s 0m0.444s 0m0.552s 0m0.468s 0m0.452s 0m0.380s2. Среднее значение:1.
real =1,0441s2. user=0,6004s3. sys=0,4392s3. После изменения порядка прохода по массиву (a[i][k] -> a[k][i]):0m1.409s 0m1.366s 0m1.347s 0m1.360s 0m1.335s 0m1.397s 0m1.334s 0m1.335s 0m1.409s 0m1.329s0m1.140s 0m1.092s 0m1.088s 0m1.104s 0m1.048s 0m1.160s 0m1.112s 0m1.084s 0m1.104s 0m1.076s0m0.264s 0m0.268s 0m0.256s 0m0.252s 0m0.284s 0m0.232s 0m0.220s 0m0.244s 0m0.296s 0m0.252s4.
Среднее значение:1. real=1,3621s2. user=1,1008s3. sys=0,2568sОбъяснение замеров:1. время real не всегда совпадает в временем user + sys, это может быть связано с тем, что real – этовремя которое прошло, user – это процессорное время которое было затрачено на работупрограммы пользователя, а sys время, затраченное на работу системы (вернее системныхвызовов)Таким образом, если система многопроцессорная, то время real может быть меньше, чем времяuser+sys, а может быть и больше, если переключение контекста происходило слишком часто.2.
Время работы после изменения порядка прохода по массиву (я рассматриваю время user, потомучто время sys слишком сильно зависит от того, что происходит в операционной системе, а этонеподконтрольные процессы) изменилось в среднем примерно на 0,5004s. Это связанно с тем, чторазмер массива, с которым работает программа, равен 381 Мб (4*10000*10000 (4 байта – размерfloat)), в то время, как L1 кеш используемого процессора равен 128 Кб, а L2 = 3Мб, что приводит кмногократной перезаписи кеша, и увеличивает время выполнения user.Количество используемой памяти было выявлено и практически через скрипт:#! /bin/bash./b &pmap -d $!Который вывел объём аллоцированной памяти процессом в 394564K3.
Замеры при помощи утилиты gprofДанная утилита может выводить количество времени, которое выполнялась та или иная функция впрограмме и общее количество времени, которое работала программа (конечно же есть ещёогромное количество флагов отвечающих за разные опции, особенности и модификациипрофилирования, но основная задача именно такая)Для использования этой утилиты, необходимо скомпилировать программу с флагом gcc –pgТеперь после обычного запуска программы будет сгенерирован файл под названием gmon.out. Ипосле этого можно будет проанализировать произошедшее при помощи gprof.Сначала, я укажу основную расшифровку значений, которые выдаёт gprof, после чего укажу самизначения.1. Расшифровка:1.
% time - the percentage of the total running time of the program used by this function.2. Cumulative seconds - a running sum of the number of seconds accounted for by this function andthose listed above it.3. Self seconds - the number of seconds accounted for by this function alone. This is the major sortfor this listing.4. Calls - the number of times this function was invoked, if this function is profiled, else blank.5. Self ms/call - the average number of milliseconds spent in this function per call, if this function isprofiled, else blank.6. Total ms/call - the average number of milliseconds spent in this function and its descendents percall, if this function is profiled, else blank.7. Name - the name of the function. This is the minor sort for this listing.
The index shows thelocation of the function in the gprof listing. If the index is in parenthesis it shows where it wouldappear in the gprof listing if it were to be printed.2. gprof -z выдаёт список всех функций в программе и время их работы:1. Each sample counts as 0.01 seconds.2. % cumulative selfself total3. time seconds seconds calls Ts/call Ts/call name4. 101.20 0.67 0.67main5. 0.00 0.67 0.00__do_global_dtors_aux6.
0.00 0.67 0.00__do_global_dtors_aux_fini_array_entry7. 0.00 0.67 0.00__frame_dummy_init_array_entry8. 0.00 0.67 0.00__gmon_start__9. 0.00 0.67 0.00__libc_csu_fini10. 0.00 0.67 0.00__libc_csu_init11. 0.00 0.67 0.00_fini12. 0.00 0.67 0.00_init13. 0.00 0.67 0.00_start14. 0.00 0.67 0.00atexit15.
0.00 0.67 0.00call_gmon_start16. 0.00 0.67 0.00data_start17. 0.00 0.67 0.00deregister_tm_clones18. 0.00 0.67 0.00frame_dummy19. 0.00 0.67 0.00register_tm_clonesИз таблицы видно, что основное время выполнения занимает функция main, которая перебираетвсе элементы массива. В то время, как служебные функции обёртки почти не занимают времени.3. Можно было вывести информацию и только по фунции main, используя вызов gproof –f main :Each sample counts as 0.01 seconds.% cumulative selfself totaltime seconds seconds calls Ts/call Ts/call name101.20 0.67 0.67main4.
Можно так же просто ограничиться списком функций в программе используя gprof –r :_init_start__gmon_start__call_gmon_startderegister_tm_clonesregister_tm_clones__do_global_dtors_auxframe_dummymain__libc_csu_fini__libc_csu_initatexit_fini__frame_dummy_init_array_entry__do_global_dtors_aux_fini_array_entrydata_start5. Если изменить порядок индексации при переборе массива (a[i][k] -> a[k][i]):1. Each sample counts as 0.01 seconds.2. % cumulative selfself total3. time seconds seconds calls Ts/call Ts/call name4. 101.20 1.40 1.40main5. 0.00 1.40 0.00__do_global_dtors_aux6.
0.00 1.40 0.00__do_global_dtors_aux_fini_array_entry7. 0.00 1.40 0.00__frame_dummy_init_array_entry8. 0.00 1.40 0.00__gmon_start__9. 0.00 1.40 0.00__libc_csu_fini10. 0.00 1.40 0.00__libc_csu_init11. 0.00 1.40 0.00_fini12. 0.00 1.40 0.00_init13. 0.00 1.40 0.00_start14. 0.00 1.40 0.00atexit15. 0.00 1.40 0.00call_gmon_start16. 0.00 1.40 0.00data_start17. 0.00 1.40 0.00deregister_tm_clones18.
0.00 1.40 0.00frame_dummy19. 0.00 1.40 0.00register_tm_clonesЗаметим, что время выполнения функции main указанное в gprof не сильно отличается от указанногопосле измерений через функцию time. Ну собственно так оно и должно быть. (хотя во втором случаеотличается на заметную величину, однако это связанно с каким-то изменениями в нагрузке насистему, потому что time проведённые незамедлительно после gprof указал на почти тот жерезультат), а результат указанный в самом первом пункте этой работы был проведён достаточнодавно на тот момент.Также хочу отметить, что gprof в отличие от time показывает всё время выполнения процесса, с учётомсистемных затрат, которые в time указываются через sys.4. Опыт с rdtsc1.
Несколько важных комментариев:1. Обычно rdtsc даёт оченьхорошую точность вплоть до наносекунд.2. Ассемблерная команда rdtsc возвращает количество тиков с момента старта компьютера впаре регистров edx:eax вне зависимости от разрядности операционной системы.3. Для того, чтобы перевести в 64-разрядной системе значение в rax можно использоватьассемблерную вставку:shl rdx, 32 // left shift for 32 bitsor rax, rdx // Compose both registers in 64 bit RAXоднако я предпочту сделать это методами си4. После этого мы будем использовать возможность связывания ассемблера с описаннымипеременными языка си, таким образом, получим следующий код:(оченьмногоможнопрочитатьпроассемблерныевставкипоссылкеhttp://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html)unsigned long long int rdtsc(void){unsigned long long int x;unsigned a, d;__asm__ volatile("rdtsc" : "=a" (a), "=d" (d));// После первого двоеточия указываются операнды вывода, первая «a» означаетрегистр eax, вторая «a» – внешнюю переменную объявленную в коде выше, аналогично с «d»return ((unsigned long long)a) | (((unsigned long long)d) << 32);}Именно этот код я буду использовать в замерах.5.
Однако, вообще говоря, существует множество более человечных способов дляпрограммиста использования rdtsc:Под windows например, можно подключить библиотеку intrin.h в которой определена__rdtsc(); или её простая альтернатива getTimeStamp, тело которой выглядит так:__int64 getTimeStamp(){return __rdtsc();}Пример использования может быть таким:// rdtsc.cpp// processor: x86, x64#include <stdio.h>#include <intrin.h>#pragma intrinsic(__rdtsc)// Intrinsic – обязателенint main(){unsigned __int64 i;i = __rdtsc();printf_s("%I64d ticks\n", i);}Вывод: 3363423610155519 ticks2. Я проводил тесты, используя функцию с ассемблерной вставкой, и получил следующиерезультаты, которые вполне совпали с другими способами измерения:number of ticks = 1584771812number of ticks = 1566574686number of ticks = 1658164821number of ticks = 1592471582number of ticks = 1569720530number of ticks = 1582264168number of ticks = 1570760025number of ticks = 1593575535number of ticks = 1629494500number of ticks = 1573569621среднее = 1592136728с учётом тактовой частоты процессора это примерно 0,663 секунды,После изменения порядка просмотра массива в цикле (a[i][k] -> a[k][i]):number of ticks = 3317490683number of ticks = 3345373438number of ticks = 3298421271number of ticks = 3212642912number of ticks = 3191041134number of ticks = 3228493816number of ticks = 3199944640number of ticks = 3186065623number of ticks = 3398632487number of ticks = 3270805276среднее = 3264891128с учётом тактовой частоты процессора это примерно 1,36 секундыТестирование под windows1.
Характеристики системы:1. Процессор - Core 2 Duo - 2 ядра по 2,4 GHz (используется конечно же одно (за исключениемтого, что некоторые вызовы оси могут быть паралельны))2. Windows 7 x64 – хостовая машина (не виртуальная)2. Компиляция с полным отключением оптимизации, тестирование было через __rdtsc () (смотри примериспользования выше)3. Результаты (компиляция была в режиме Release x64)number of ticks = 1272429415number of ticks = 1217791503number of ticks = 1211113828number of ticks = 1217113165number of ticks = 1214894971number of ticks = 1201390669number of ticks = 1199625319number of ticks = 1193677596number of ticks = 1199743398number of ticks = 1209035727среднее значение = 1213681559,1с учётом тактовой частоты это 0,505s – что несколько быстрее, чем в случаях тестирования из под linux,установленного как виртуальная машина4.
Характеристики
Тип файла PDF
PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.
Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.