这是c++和Python之间CPU时间比较的有效方法吗?
Is this a valid method for CPU time comparison between C++ and Python?
我感兴趣的是比较CPU时间一些代码部分编写的c++和Python(运行在Linux上)。下面的方法会在两者之间产生一个"公平"的比较吗?
Python 使用资源模块:import resource
def cpu_time():
return resource.getrusage(resource.RUSAGE_SELF)[0]+ # time in user mode
resource.getrusage(resource.RUSAGE_SELF)[1] # time in system mode
允许这样计时:
def timefunc( func ):
start=cpu_time()
func()
return (cpu_time()-start)
然后测试如下:
def f():
for i in range(int(1e6)):
pass
avg = 0
for k in range(10):
avg += timefunc( f ) / 10.0
print avg
=> 0.002199700000000071
<标题> c++ h1> 用ctime
lib:
#include <ctime>
#include <iostream>
int main() {
double avg = 0.0;
int N = (int) 1e6;
for (int k=0; k<10; k++) {
clock_t start;
start = clock();
for (int i=0; i<N; i++) continue;
avg += (double)(clock()-start) / 10.0 / CLOCKS_PER_SEC;
}
std::cout << avg << 'n';
return 0;
}
生成0.002
。
问题:
- 我读过c++
clock()
测量CPU时间,这是我所追求的,但我似乎找不到它是否包括用户和系统时间。 c++的 - 结果不太精确。为什么呢?
- 如上所述的总体比较公平性。
按照David在注释中的建议更新了c++代码:
#include <sys/resource.h>
#include <iostream>
int main() {
double avg = 0.0;
int N = (int) 1e6;
int tally = 0;
struct rusage usage;
struct timeval ustart, ustop, sstart, sstop;
getrusage(RUSAGE_SELF, &usage);
ustart = usage.ru_utime;
sstart = usage.ru_stime;
for (int k=0; k<10; k++) {
ustart = usage.ru_utime;
sstart = usage.ru_stime;
for (int i=0; i<N; i++) continue;
getrusage(RUSAGE_SELF, &usage);
ustop = usage.ru_utime;
sstop = usage.ru_stime;
avg += (
(ustop.tv_sec+ustop.tv_usec/1e6+
sstop.tv_sec+sstop.tv_usec/1e6)
-
(ustart.tv_sec+ustart.tv_usec/1e6+
sstart.tv_sec+sstart.tv_usec/1e6)
) / 10.0;
}
std::cout << avg << 'n';
return 0;
}
运行:g++ -O0 cpptimes.cpp ; ./a.out
=> 0.0020996
g++ -O1 cpptimes.cpp ; ./a.out
=> 0
所以我想getrusage
给我一点更好的分辨率,但我不确定我应该读多少。
文档说:
"返回进程从与程序执行相关的实现定义时代开始以来所使用的近似处理器时间。"
将结果值转换为秒。这很模糊。CLOCK_PER_SEC
设置为10^6
,近似表示低分辨率,并不是说当前时钟超过1000快,结果是四舍五入的。这可能不是一个非常专业的术语,但它是合适的。我测试的所有地方的实际分辨率都是100Hz = 0.01 s。这种情况已经持续好多年了。在这里注明日期http://www.guyrutenberg.com/2007/09/10/resolution-problems-in-clock/。
然后文档后面跟着:"在posix兼容系统上,时钟id为CLOCK_PROCESS_CPUTIME_ID的clock_gettime提供更好的分辨率。"
:
这只是CPU时间。但是2个线程= 2*CPU时间。
如前所述,它根本不适合细粒度测量。
在我看来,测量挂钟是唯一明智的事情,但这是一个相当个人的观点。特别是对于多线程应用程序和一般的多处理。否则
system
+user
的结果应该相似。
编辑:3。这当然适用于计算任务。如果您的进程使用sleep
或放弃执行返回给系统,那么测量CPU时间可能更可行。另外,关于clock
分辨率是呃…坏的。确实如此,但公平地说,有人可能会认为不应该度量如此短的计算。在我看来,这太糟糕了,但如果你在几秒钟内测量时间,我想这很好。我个人会使用其他可用的工具。
设置优化标志当然会有很大的不同。
c++是一种需要编译优化的语言,特别是当所讨论的代码使用c++标准库中的容器和迭代器时。
一个简单的++iterator
在未优化编译时从一个相当大的函数调用链缩小到一个或两个程序集语句。也就是说,我知道编译器会对测试代码做什么。任何合适的优化编译器都会使for (int i=0; i<N; i++) continue;
循环消失。这是工作中的as-if规则。该循环不做任何事情,因此编译器可以自由地将其视为根本不存在。
当我观察一个可疑的CPU占用者的CPU行为时,我编写了一个简单的驱动程序(在一个单独的文件中),该驱动程序多次调用可疑的函数,有时调用的次数非常多。我在启用优化的情况下编译要测试的功能,但在禁用优化的情况下编译驱动程序。我不希望一个过于聪明的优化编译器看到这100,000个对function_to_be_tested()
的调用可以被拉出循环,然后进一步优化循环。
在单个调用开始计时器和停止计时器之间多次调用test函数有许多可靠的理由。这就是为什么python有timeit
模块。
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法