ответ на задание 1 (1124141)
Текст из файла
Василенко Анатолий
421 группа
Тестирование под Linux:
-
Характеристики системы:
-
Процессор - Core 2 Duo - 2 ядра по 2,4 GHz (используется конечно же одно (за исключением того, что некоторые вызовы оси могут быть паралельны))
-
Linux x64 - установлен на вирутальную машину из под vmware
-
Процессор поддерживает Intel VT (Virutalization Technology)
-
Замеры при помощи утилиты time:
-
Было сделано 10 замеров:
real
user
sys
0m1.028s
0m0.664s
0m0.360s
0m1.089s
0m0.612s
0m0.472s
0m1.048s
0m0.608s
0m0.432s
0m1.092s
0m0.608s
0m0.484s
0m0.942s
0m0.588s
0m0.348s
0m1.047s
0m0.604s
0m0.444s
0m1.139s
0m0.580s
0m0.552s
0m0.986s
0m0.508s
0m0.468s
0m1.078s
0m0.620s
0m0.452s
0m0.992s
0m0.612s
0m0.380s
-
Среднее значение:
-
real =1,0441s
-
user=0,6004s
-
sys=0,4392s
-
После изменения порядка прохода по массиву (a[i][k] -> a[k][i]):
real user sys | 0m1.409s 0m1.140s 0m0.264s | 0m1.366s 0m1.092s 0m0.268s | 0m1.347s 0m1.088s 0m0.256s | 0m1.360s 0m1.104s 0m0.252s | 0m1.335s 0m1.048s 0m0.284s | 0m1.397s 0m1.160s 0m0.232s | 0m1.334s 0m1.112s 0m0.220s | 0m1.335s 0m1.084s 0m0.244s | 0m1.409s 0m1.104s 0m0.296s | 0m1.329s 0m1.076s 0m0.252s |
Среднее значение:
-
real=1,3621s
-
user=1,1008s
-
sys=0,2568s
Объяснение замеров:
-
время real не всегда совпадает в временем user + sys, это может быть связано с тем, что real – это время которое прошло, user – это процессорное время которое было затрачено на работу программы пользователя, а sys время, затраченное на работу системы (вернее системных вызовов)
Таким образом, если система многопроцессорная, то время real может быть меньше, чем время user+sys, а может быть и больше, если переключение контекста происходило слишком часто.
-
Время работы после изменения порядка прохода по массиву (я рассматриваю время user, потому что время sys слишком сильно зависит от того, что происходит в операционной системе, а это неподконтрольные процессы) изменилось в среднем примерно на 0,5004s. Это связанно с тем, что размер массива, с которым работает программа, равен 381 Мб (4*10000*10000 (4 байта – размер float)), в то время, как L1 кеш используемого процессора равен 128 Кб, а L2 = 3Мб, что приводит к многократной перезаписи кеша, и увеличивает время выполнения user.
Количество используемой памяти было выявлено и практически через скрипт:
#! /bin/bash
./b &
pmap -d $!
Который вывел объём аллоцированной памяти процессом в 394564K
-
Замеры при помощи утилиты gprof
Данная утилита может выводить количество времени, которое выполнялась та или иная функция в программе и общее количество времени, которое работала программа (конечно же есть ещё огромное количество флагов отвечающих за разные опции, особенности и модификации профилирования, но основная задача именно такая)
Для использования этой утилиты, необходимо скомпилировать программу с флагом gcc –pg
Теперь после обычного запуска программы будет сгенерирован файл под названием gmon.out. И после этого можно будет проанализировать произошедшее при помощи gprof.
Сначала, я укажу основную расшифровку значений, которые выдаёт gprof, после чего укажу сами значения.
-
Расшифровка:
-
% time - the percentage of the total running time of the program used by this function.
-
Cumulative seconds - a running sum of the number of seconds accounted for by this function and those listed above it.
-
Self seconds - the number of seconds accounted for by this function alone. This is the major sort for this listing.
-
Calls - the number of times this function was invoked, if this function is profiled, else blank.
-
Self ms/call - the average number of milliseconds spent in this function per call, if this function is profiled, else blank.
-
Total ms/call - the average number of milliseconds spent in this function and its descendents per call, if this function is profiled, else blank.
-
Name - the name of the function. This is the minor sort for this listing. The index shows the location of the function in the gprof listing. If the index is in parenthesis it shows where it would appear in the gprof listing if it were to be printed.
-
-
gprof -z выдаёт список всех функций в программе и время их работы:
|
Из таблицы видно, что основное время выполнения занимает функция main, которая перебирает все элементы массива. В то время, как служебные функции обёртки почти не занимают времени.
-
Можно было вывести информацию и только по фунции main, используя вызов gproof –f main :
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
101.20 0.67 0.67 main
-
Можно так же просто ограничиться списком функций в программе используя gprof –r :
_init
_start
__gmon_start__
call_gmon_start
deregister_tm_clones
register_tm_clones
__do_global_dtors_aux
frame_dummy
main
__libc_csu_fini
__libc_csu_init
atexit
_fini
__frame_dummy_init_array_entry
__do_global_dtors_aux_fini_array_entry
data_start
-
Если изменить порядок индексации при переборе массива (a[i][k] -> a[k][i]):
|
Заметим, что время выполнения функции main указанное в gprof не сильно отличается от указанного после измерений через функцию time. Ну собственно так оно и должно быть. (хотя во втором случае отличается на заметную величину, однако это связанно с каким-то изменениями в нагрузке на систему, потому что time проведённые незамедлительно после gprof указал на почти тот же результат), а результат указанный в самом первом пункте этой работы был проведён достаточно давно на тот момент.
Также хочу отметить, что gprof в отличие от time показывает всё время выполнения процесса, с учётом системных затрат, которые в time указываются через sys.
-
Опыт с rdtsc
-
Несколько важных комментариев:
-
Обычно rdtsc даёт оченьхорошую точность вплоть до наносекунд.
-
Ассемблерная команда rdtsc возвращает количество тиков с момента старта компьютера в паре регистров edx:eax вне зависимости от разрядности операционной системы.
-
Для того, чтобы перевести в 64-разрядной системе значение в rax можно использовать ассемблерную вставку:
-
-
shl rdx, 32 // left shift for 32 bits
or rax, rdx // Compose both registers in 64 bit RAX
однако я предпочту сделать это методами си
-
После этого мы будем использовать возможность связывания ассемблера с описанными переменными языка си, таким образом, получим следующий код:
(очень много можно прочитать про ассемблерные вставки по ссылке 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);
}
Именно этот код я буду использовать в замерах.
-
Однако, вообще говоря, существует множество более человечных способов для программиста использования 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 ticks
-
Я проводил тесты, используя функцию с ассемблерной вставкой, и получил следующие результаты, которые вполне совпали с другими способами измерения:
number of ticks = 1584771812
number of ticks = 1566574686
number of ticks = 1658164821
number of ticks = 1592471582
number of ticks = 1569720530
Характеристики
Тип файла документ
Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.
Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.
Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.