当前位置: 首页 > 面试题库 >

编写一个C程序来测量在Linux OS中上下文切换所花费的时间

谭成业
2023-03-14
问题内容

我们可以编写一个ac程序来找出在Linux中进行上下文切换所花费的时间吗?如果有的话,您可以共享代码吗?谢谢


问题答案:

对切​​换时间进行性能分析非常困难,但是内核内延迟性能分析工具以及oprofile(可以对内核本身进行性能分析)将为您提供帮助。

为了对交互式应用程序的性能进行基准测试,我编写了一个名为latencybench的小工具,用于测量意外的延迟峰值:

// Compile with g++ latencybench.cc -o latencybench -lboost_thread-mt
// Should also work on MSVC and other platforms supported by Boost.

#include <boost/format.hpp>
#include <boost/thread/thread.hpp>
#include <boost/date_time.hpp>
#include <algorithm>
#include <cstdlib>
#include <csignal>

volatile bool m_quit = false;

extern "C" void sighandler(int) {
    m_quit = true;
}

std::string num(unsigned val) {
    if (val == 1) return "one occurrence";
    return boost::lexical_cast<std::string>(val) + " occurrences";
}

int main(int argc, char** argv) {
    using namespace boost::posix_time;
    std::signal(SIGINT, sighandler);
    std::signal(SIGTERM, sighandler);
    time_duration duration = milliseconds(10);
    if (argc > 1) {
        try {
            if (argc != 2) throw 1;
            unsigned ms = boost::lexical_cast<unsigned>(argv[1]);
            if (ms > 1000) throw 2;
            duration = milliseconds(ms);
        } catch (...) {
            std::cerr << "Usage: " << argv[0] << " milliseconds" << std::endl;
            return EXIT_FAILURE;
        }
    }
    typedef std::map<long, unsigned> Durations;
    Durations durations;
    unsigned samples = 0, wrongsamples = 0;
    unsigned max = 0;
    long last = -1;
    std::cout << "Measuring actual sleep delays when requesting " << duration.total_milliseconds() << " ms: (Ctrl+C when done)" << std::endl;
    ptime begin = boost::get_system_time();
    while (!m_quit) {
        ptime start = boost::get_system_time();
        boost::this_thread::sleep(start + duration);
        long actual = (boost::get_system_time() - start).total_milliseconds();
        ++samples;
        unsigned num = ++durations[actual];
        if (actual != last) {
            std::cout << "\r  " << actual << " ms " << std::flush;
            last = actual;
        }
        if (actual != duration.total_milliseconds()) {
            ++wrongsamples;
            if (num > max) max = num;
            std::cout << "spike at " << start - begin << std::endl;
            last = -1;
        }
    }
    if (samples == 0) return 0;
    std::cout << "\rTotal measurement duration:  " << boost::get_system_time() - begin << "\n";
    std::cout << "Number of samples collected: " << samples << "\n";
    std::cout << "Incorrect delay count:       " << wrongsamples << boost::format(" (%.2f %%)") % (100.0 * wrongsamples / samples) << "\n\n";
    std::cout << "Histogram of actual delays:\n\n";
    unsigned correctsamples = samples - wrongsamples;
    const unsigned line = 60;
    double scale = 1.0;
    char ch = '+';
    if (max > line) {
        scale = double(line) / max;
        ch = '*';
    }
    double correctscale = 1.0;
    if (correctsamples > line) correctscale = double(line) / correctsamples;
    for (Durations::const_iterator it = durations.begin(); it != durations.end(); ++it) {
        std::string bar;
        if (it->first == duration.total_milliseconds()) bar = std::string(correctscale * it->second, '>');
        else bar = std::string(scale * it->second, ch);
        std::cout << boost::format("%5d ms | %s %d") % it->first % bar % it->second << std::endl;
    }
    std::cout << "\n";
    std::string indent(30, ' ');
    std::cout << indent << "+-- Legend ----------------------------------\n";
    std::cout << indent << "|  >  " << num(1.0 / correctscale) << " (of " << duration.total_milliseconds() << " ms delay)\n";
    if (wrongsamples > 0) std::cout << indent << "|  " << ch << "  " << num(1.0 / scale) << " (of any other delay)\n";
}

在Ubuntu 2.6.32-14-通用内核上的结果。在测量时,我正在编译具有四个核心的C ++代码,并同时玩OpenGL图形游戏(使之更有趣):

Total measurement duration:  00:01:45.191465
Number of samples collected: 10383
Incorrect delay count:       196 (1.89 %)

Histogram of actual delays:

   10 ms | >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 10187
   11 ms | *************************************************** 70
   12 ms | ************************************************************ 82
   13 ms | ********* 13
   14 ms | ********* 13
   15 ms | ** 4
   17 ms | *** 5
   18 ms | * 2
   19 ms | **** 6
   20 ms |  1

                              +-- Legend ----------------------------------
                              |  >  169 occurrences (of 10 ms delay)
                              |  *  one occurrence (of any other delay)

使用rt修补的内核,我可以获得更好的结果,仅10-12 ms。

打印输出中的图例似乎存在舍入错误或某些错误(并且粘贴的源代码不是完全相同的版本)。我从未真正完善过此应用程序的发行版…



 类似资料:
  • 问题内容: 假设我正在测试Java服务器应用程序。我知道需要多少时间才能完成测试。现在,我想知道该测试期间在GC上花费了多少。我该怎么做? 问题答案: 最简单的方法是在启动JVM时使用和选项。我认为它可以打印出垃圾收集需要多长时间。 http://www.oracle.com/technetwork/java/javase/tech/vmoptions- jsp-140102.html

  • 问题内容: 为什么在执行中断处理程序时无法进行上下文切换?更具体地说,在linux内核中,中断处理程序在被中断的进程的上下文中运行。为什么不能在中断处理程序中进行上下文切换来调度另一个进程? 问题答案: 在多处理器上,上下文切换当然可以在执行中断处理程序时发生。实际上,将很难预防。 根据定义,在单CPU机器上,它一次只能运行一个控制线程。它只有一个寄存器集,一个ALU,等等。因此,如果中断处理程序

  • 问题内容: 我需要获取执行时间(以毫秒为单位)。 当时接受的答案是使用newDate()。getTime()。但是,我们现在都可以同意使用标准performance.now()API更合适。因此,我正在更改对此答案的公认答案。 问题答案: 使用 performance.now(): :需要导入类 使用 console.time: (非标准) (living standard) 注意 : 传递给和方

  • 本文向大家介绍编写一个C程序以打印所有文件和文件夹。,包括了编写一个C程序以打印所有文件和文件夹。的使用技巧和注意事项,需要的朋友参考一下 文件是记录的集合(或)在硬盘上永久存储数据的位置。 通过使用C命令,我们可以以不同的方式访问文件。 文件操作 下面给出的是可以用C编程语言对文件执行的操作- 命名文件 打开文件 从文件读取 写入文件 关闭档案 语法 下面分别给出了打开和命名文件的语法- 例如,

  • 本文向大家介绍编写一个在C和C ++编程中产生不同结果的程序,包括了编写一个在C和C ++编程中产生不同结果的程序的使用技巧和注意事项,需要的朋友参考一下 编写一个可编译并在c和c ++中运行并产生不同结果的程序。 使用c和c ++进行编译时,有多种类型的程序会给出不同的结果。 一世。使用字符字面量-c和c ++都以不同的方式对待字符。在C中,它们被视为整数文字,而在C ++中,它们被视为字符。