R 为什么';测量负执行时间';出现错误?(如何应对?)

R 为什么';测量负执行时间';出现错误?(如何应对?),r,microbenchmark,R,Microbenchmark,我开始了解microbenchmark的一些特性。我实现了Hadley Wickham出版物中的一个示例代码,收到了一个错误,我找不到任何精确的信息,也无法处理。提前感谢您的任何解释/提示等 示例代码: library(microbenchmark) f <- function() NULL microbenchmark( NULL, f() ) 更新。这是我的seesionInfo()控制台输出: Error in microbenchmark(NULL, f()) :

我开始了解microbenchmark的一些特性。我实现了Hadley Wickham出版物中的一个示例代码,收到了一个错误,我找不到任何精确的信息,也无法处理。提前感谢您的任何解释/提示等

示例代码:

library(microbenchmark)

f <- function() NULL
microbenchmark(
  NULL,
  f()
)
更新。这是我的
seesionInfo()
控制台输出:

Error in microbenchmark(NULL, f()) : 
  Measured negative execution time! Please investigate and/or contact the package author.
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=Polish_Poland.1250  LC_CTYPE=Polish_Poland.1250    LC_MONETARY=Polish_Poland.1250
[4] LC_NUMERIC=C                   LC_TIME=Polish_Poland.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_0.9.3.1      microbenchmark_1.3-0

loaded via a namespace (and not attached):
 [1] colorspace_1.2-4   dichromat_2.0-0    digest_0.6.3       grid_3.0.2         gtable_0.1.2       labeling_0.2      
 [7] MASS_7.3-29        munsell_0.4.2      plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2      tools_3.0.2    
更新2。该软件包的作者向我询问了一些进一步的信息:

  • R变量
    R.version

    R.版本 _
    平台x86_64-w64-mingw32
    拱门x86_64
    os mingw32
    系统x86_64,mingw32
    状态
    专业3
    小调0.2
    2013年
    第09个月
    第25天
    svn修订版63987
    语言R
    version.string R版本3.0.2(2013-09-25) 绰号飞盘帆船

  • 我的计算机中CPU的品牌、型号和速度:

处理器:英特尔(R)Core(TM)i7-2600K处理器@3.40GHz 3.70GHz

内存:16,0 GB

系统类型:64位

更新3。

我注意到上面代码的一个修改返回了正确的结果:

> ### 1 
> f <- function(){NULL} 
> microbenchmark(NULL, f())
Error in microbenchmark(NULL, f()) : 
  Measured negative execution time! Please investigate and/or contact the package author.
> 
> 
> ### 2 
> f <- function(){ } 
> microbenchmark(NULL, f())
Error in microbenchmark(NULL, f()) : 
  Measured negative execution time! Please investigate and/or contact the package author.
> 
> 
> ### 3 
> f <- function(){NULL} 
> microbenchmark(f())
Unit: nanoseconds
 expr min lq median uq  max neval
  f()   0  1      1  1 7245   100
> 
> ### 4 
> f <- function(){ } 
> microbenchmark(f())
Error in microbenchmark(f()) : 
  Measured negative execution time! Please investigate and/or contact the package author.
###1
>f微基准(NULL,f())
微基准中出错(NULL,f()):
测量负执行时间!请调查和/或联系软件包作者。
> 
> 
> ### 2 
>f微基准(NULL,f())
微基准中出错(NULL,f()):
测量负执行时间!请调查和/或联系软件包作者。
> 
> 
> ### 3 
>f微基准(f())
单位:纳秒
expr最小lq中值uq最大neval
f()0117245100
> 
> ### 4 
>f微基准(f())
microbenchmark(f())中出错:
测量负执行时间!请调查和/或联系软件包作者。

根据您使用的操作系统,您计算机上的高性能计时器子系统安装的驱动程序可能有问题

在Windows land中,可以通过
QueryPerformanceCounter
QueryPerformanceFrequency
函数访问HPT。QPF告诉您计数器滴答声的频率,从而告诉您计数器的准确性;QPC/QPF以秒为单位给出一个值,通常是计算机启动的时间

问题在于,对这个API的驱动程序支持有时是参差不齐的。AMD在过去尤其遇到过麻烦,我亲身经历过这一点

您可以尝试在线搜索CPU和/或主板的驱动程序,以查看是否缺少驱动程序。这可能会解决这个问题

编辑:

@MatthewLundberg的观点是,不同内核上的rdtsc指令有时有点偏离。解决这个问题的一种廉价方法是改变程序的cpu相关性,使其只在一个内核上运行


假设您使用的是Win Vista或更高版本,进入任务管理器,右键单击运行代码的进程,选择“Affinity…”并将其限制为仅一个处理器(第一个CPU很好)。

正如另一个答案所述,Windows计时器似乎没有足够的精度来测量执行时间,即,执行时间小于1纳秒。如果我们将
nanotimer.c
文件中的包源简单更改为
do_microtiming()
c函数

if (start < end) {
    const nanotime_t diff = end - start;
    if (diff < overhead) {
        ret[i] = R_NaReal;
        n_under_overhead++;
    } else {
        ret[i] = diff - overhead;
    }
} else if( start == end ) { // <----- This elseif is our minor edit
  error( "Start and end have same time. Not enough precision to measure execution time" );
} else {
    error("Measured negative execution time! Please investigate and/or "
          "contact the package author.");
}
if(开始<结束){
const nanotime_t diff=结束-开始;
if(差异<开销){
ret[i]=R_NaReal;
开销++下的n_;
}否则{
ret[i]=差异-开销;
}

}else if(start==end){/解决此问题的另一种方法是增加您基准测试的表达式的工作量。我在尝试了解
microbenchmark
函数如何工作时遇到了相同的问题,并通过更改表达式避免了此问题(将功能
f1
f2
f3
)测试为更具挑战性的功能:

library(microbenchmark)

f1 <- function() { factorial(10) }
f2 <- function() { 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 }
f3 <- function() { factorial(16) / (11 * 12 * 13 * 14 * 15 * 16) }
benchmarkResults <- microbenchmark(f1(), f2(), f3(), times = 1000L)
print(benchmarkResults)
库(微基准)

f1我不在32位Ubuntu12.04,R-devel上复制(sessionInfo()的结果可能会有帮助--
NULL
的中值时间为26纳秒,
f()的中值时间为294纳秒)
。我怀疑您的问题只是该函数占用的时间太少,导致计时不准确……我也没有在MacOS X.5 R 3.0.2下复制(我目前无法访问Windows系统)计时函数在Windows上调用QPC。我不知道您的操作系统是否调用RDTSC来实现QPC(某些版本有)。如果是这样,并且您正在运行一个古老的多核或多CPU(Core 2或更早版本),RDTSC可以在进程在两个核之间跳跃时看到时间回归。您联系过软件包作者吗?最终我联系了(就在此时)。感谢您的警告!感谢您的解释和建议如何修复它!我已经安装了“英特尔驱动程序更新实用程序”为我的计算机建议的更新/新驱动程序,并且我不断收到相同的错误。暂时我只需移动到
rbenchmark
,它确实与我的电脑一起工作。一种指定它的方法Windows上的y是通过使用
start
/affinity
标志来创建进程的。
start/affinity 1R
例如,将进程保持在核心0上。我遵循了MatthewLundberg的提示和antiduh的指南如何在Windows 7中进行更改,将使用的处理器数量缩小到一个([1])对于
rstudio.exe*32
rsession.exe
本身已更改),然后在
rstudio
中运行
restart R
,然后再次检查是否保留了处理器数量减少,然后再次运行
microbenchmark
代码
library(microbenchmark)

f1 <- function() { factorial(10) }
f2 <- function() { 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 }
f3 <- function() { factorial(16) / (11 * 12 * 13 * 14 * 15 * 16) }
benchmarkResults <- microbenchmark(f1(), f2(), f3(), times = 1000L)
print(benchmarkResults)