PageRenderTime 19ms CodeModel.GetById 9ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/libavutil/timer.h

http://github.com/FFmpeg/FFmpeg
C Header | 141 lines | 101 code | 17 blank | 23 comment | 12 complexity | f1dbab1325aaed3d51c4f6e6e55ea57d MD5 | raw file
  1/*
  2 * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  3 *
  4 * This file is part of FFmpeg.
  5 *
  6 * FFmpeg is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU Lesser General Public
  8 * License as published by the Free Software Foundation; either
  9 * version 2.1 of the License, or (at your option) any later version.
 10 *
 11 * FFmpeg is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14 * Lesser General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU Lesser General Public
 17 * License along with FFmpeg; if not, write to the Free Software
 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 19 */
 20
 21/**
 22 * @file
 23 * high precision timer, useful to profile code
 24 */
 25
 26#ifndef AVUTIL_TIMER_H
 27#define AVUTIL_TIMER_H
 28
 29#include "config.h"
 30
 31#if CONFIG_LINUX_PERF
 32# ifndef _GNU_SOURCE
 33#  define _GNU_SOURCE
 34# endif
 35# include <unistd.h> // read(3)
 36# include <sys/ioctl.h>
 37# include <asm/unistd.h>
 38# include <linux/perf_event.h>
 39#endif
 40
 41#include <stdlib.h>
 42#include <stdint.h>
 43#include <inttypes.h>
 44
 45#if HAVE_MACH_ABSOLUTE_TIME
 46#include <mach/mach_time.h>
 47#endif
 48
 49#include "log.h"
 50
 51#if   ARCH_AARCH64
 52#   include "aarch64/timer.h"
 53#elif ARCH_ARM
 54#   include "arm/timer.h"
 55#elif ARCH_PPC
 56#   include "ppc/timer.h"
 57#elif ARCH_X86
 58#   include "x86/timer.h"
 59#endif
 60
 61#if !defined(AV_READ_TIME)
 62#   if HAVE_GETHRTIME
 63#       define AV_READ_TIME gethrtime
 64#   elif HAVE_MACH_ABSOLUTE_TIME
 65#       define AV_READ_TIME mach_absolute_time
 66#   endif
 67#endif
 68
 69#ifndef FF_TIMER_UNITS
 70#   define FF_TIMER_UNITS "UNITS"
 71#endif
 72
 73#define TIMER_REPORT(id, tdiff)                                           \
 74    {                                                                     \
 75        static uint64_t tsum   = 0;                                       \
 76        static int tcount      = 0;                                       \
 77        static int tskip_count = 0;                                       \
 78        static int thistogram[32] = {0};                                  \
 79        thistogram[av_log2(tdiff)]++;                                     \
 80        if (tcount < 2                ||                                  \
 81            (tdiff) < 8 * tsum / tcount ||                                \
 82            (tdiff) < 2000) {                                             \
 83            tsum += (tdiff);                                              \
 84            tcount++;                                                     \
 85        } else                                                            \
 86            tskip_count++;                                                \
 87        if (((tcount + tskip_count) & (tcount + tskip_count - 1)) == 0) { \
 88            int i;                                                        \
 89            av_log(NULL, AV_LOG_ERROR,                                    \
 90                   "%7"PRIu64" " FF_TIMER_UNITS " in %s,%8d runs,%7d skips",          \
 91                   tsum * 10 / tcount, id, tcount, tskip_count);          \
 92            for (i = 0; i < 32; i++)                                      \
 93                av_log(NULL, AV_LOG_VERBOSE, " %2d", av_log2(2*thistogram[i]));\
 94            av_log(NULL, AV_LOG_ERROR, "\n");                             \
 95        }                                                                 \
 96    }
 97
 98#if CONFIG_LINUX_PERF
 99
100#define START_TIMER                                                         \
101    static int linux_perf_fd;                                               \
102    uint64_t tperf;                                                         \
103    if (!linux_perf_fd) {                                                   \
104        struct perf_event_attr attr = {                                     \
105            .type           = PERF_TYPE_HARDWARE,                           \
106            .size           = sizeof(struct perf_event_attr),               \
107            .config         = PERF_COUNT_HW_CPU_CYCLES,                     \
108            .disabled       = 1,                                            \
109            .exclude_kernel = 1,                                            \
110            .exclude_hv     = 1,                                            \
111        };                                                                  \
112        linux_perf_fd = syscall(__NR_perf_event_open, &attr,                \
113                                0, -1, -1, 0);                              \
114    }                                                                       \
115    if (linux_perf_fd == -1) {                                              \
116        av_log(NULL, AV_LOG_ERROR, "perf_event_open failed: %s\n",          \
117               av_err2str(AVERROR(errno)));                                 \
118    } else {                                                                \
119        ioctl(linux_perf_fd, PERF_EVENT_IOC_RESET, 0);                      \
120        ioctl(linux_perf_fd, PERF_EVENT_IOC_ENABLE, 0);                     \
121    }
122
123#define STOP_TIMER(id)                                                      \
124    ioctl(linux_perf_fd, PERF_EVENT_IOC_DISABLE, 0);                        \
125    read(linux_perf_fd, &tperf, sizeof(tperf));                             \
126    TIMER_REPORT(id, tperf)
127
128#elif defined(AV_READ_TIME)
129#define START_TIMER                             \
130    uint64_t tend;                              \
131    uint64_t tstart = AV_READ_TIME();           \
132
133#define STOP_TIMER(id)                                                    \
134    tend = AV_READ_TIME();                                                \
135    TIMER_REPORT(id, tend - tstart)
136#else
137#define START_TIMER
138#define STOP_TIMER(id) { }
139#endif
140
141#endif /* AVUTIL_TIMER_H */