CUDA 中clock() 和clock64() 的时钟测量值是多少?

Posted

技术标签:

【中文标题】CUDA 中clock() 和clock64() 的时钟测量值是多少?【英文标题】:What is the clock measure by clock() and clock64() in CUDA? 【发布时间】:2015-01-19 20:45:04 【问题描述】:

clock()clock64() 在 CUDA 中的时钟测量值是多少?

根据CUDA documentation,时钟是“每多处理器计数器”。根据我的理解,这是指主 GPU 时钟(而不是着色器时钟)。

但是当我使用主 GPU 时钟频率测量时钟计数并将其转换为时间值时,我得到的结果是实际值的两倍(我使用 cuda 事件从主机代码的内核执行时间测量实际值)。这表明clock() 返回着色器时钟频率而不是主 GPU 时钟。

我该如何解决这个困惑?

编辑: 我通过将我从 cudaGetDeviceProperties 获得的时钟频率除以 2 来计算主 GPU 时钟频率。据我了解,cudaGetDeviceProperties 给出的值是着色器时钟频率。

【问题讨论】:

主 GPU 时钟/图形核心时钟/图形时钟/核心时钟:流式多处理器运行的时钟频率。 着色器时钟/着色器核心时钟/处理器时钟/GPU时钟:执行单元(CUDA核心)运行的时钟频率。这是主 GPU 时钟值的两倍。我是这么理解的。 我可以确认在 Fermi 设备上,cudaDeviceProp::clockRate 是着色器时钟频率,即与“主”GPU 时钟相比的两倍值。在开普勒设备上,两者是相同的。如果您告诉您正在使用哪种设备,答案会更加确定。不确定clock()clock64() - 你的假设可能是正确的。 我认为@Optimus 指的是以下内容:在较旧的 GPU(例如 Fermi 系列)上,执行单元的运行速度是图形域其余部分的两倍(有时称为“热时钟”)。 nvidia-smi 分别将它们报告为“图形”和“SM”时钟。例如,在我的基于 Fermi 的 Quadro 2000 上,前者报告为 625 MHz,后者报告为 1251 MHz。据我所知,从 Kepler 开始,GPU 的所有非内存域都以相同的速度运行,即不再有 SM 热时钟。 我的设备是 Quadro 2000D。 'cudaDeviceProp::clockRate' 给出的时钟频率是 1251 MHz,这是着色器时钟频率。我感到困惑的原因是CUDA documentation 他们说“每多处理器计数器”指的是主 GPU 时钟。 @njuffa:你是如何获得 625 MHz 的?是来自数据表还是来自 CUDA 函数? 【参考方案1】:

CUDA documentation 说 clock()clock64() 返回“每多处理器计数器”是真的。但在 Fermi 架构中,clock()clock64() 实际上返回的是着色器时钟计数器。

cudaGetDeviceProperties 返回的clockRate 是着色器时钟频率。

因此,要计算时间,我们必须将 clock()clock64() 的时钟计数除以您从 cudaGetDeviceProperties 获得的着色器时钟频率。

【讨论】:

我会告诫不要将 clock()clock64() 计数转换为基于 cudaDeviceProp::clockRate 的值的时间单位,因为由于时钟提升和时钟节流,底层时钟可能会动态变化。如果我没记错的话,自费米(Fermi)以来就一直存在时钟节流以限制功耗,并且动态时钟提升是由开普勒引入的。 是的,我同意你的看法。但就我而言,我得到的值是准确的。我比较了我从clock() 获得的结果与我从 CUDA 事件获得的时间测量结果,它们几乎相似。

以上是关于CUDA 中clock() 和clock64() 的时钟测量值是多少?的主要内容,如果未能解决你的问题,请参考以下文章

CUDA clock() 导致零时钟周期

CUDA学习之使用clock()函数

0_Simple__clock

CUDA测量2个_syncthread()点之间的时间[重复]

cuda里面的核函数怎么调用第三方库的函数

SylixOS下移植glib时clock_gettime函数分析