- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用在 Windows 10 + Nvidia Gtx 970 上运行的 ArrayFire 编写测试程序。该程序用于使用 SGD 求解器训练神经网络。因此,主要计算是更新网络参数的迭代。迭代在名为 step()
的函数中进行。
除了在第一分钟执行速度极慢之外,该程序执行了预期的操作。以下是程序的输出。第一列是耗时。
ArrayFire v3.5.1 (CUDA, 64-bit Windows, build 0a675e8)Platform: CUDA Toolkit 8, Driver: CUDA Driver Version: 8000[0] GeForce GTX 970, 4096 MB, CUDA Compute 5.2 time epochs training error 5 0.002 5.6124567 6 0.007 5.5981609 7 0.010 5.3560046 8 0.015 5.2485286 9 0.020 5.1370633 10 0.022 5.1081303 .... 52 0.148 3.2528560 53 0.150 3.2425120 54 0.153 3.2180901 55 0.155 3.2048657 56 0.157 3.1949191 57 0.158 3.1816899 58 0.160 3.1717312 59 0.162 3.1597322 60 0.165 3.1370639 60 0.498 2.1359600 61 0.548 2.0685355 61 0.882 1.7098215 62 0.943 1.6575973 62 1.277 1.4156345 63 1.343 1.3845720 63 1.677 1.1789854 64 1.733 1.1549067 64 2.067 1.0162785 .... 71 4.517 0.4732214 71 4.850 0.4522045 72 4.910 0.4501807 72 5.243 0.4355422 73 5.305 0.4307187
如您所见,在第一分钟,它甚至没有完成 1/5 的 epoch。但一分钟后,它突然加速,在大约 4 秒内完成了一个 epoch。
分析数据也说明了同样的事情:在第一分钟内,函数 step()
的平均执行时间约为 500 毫秒,但在第一分钟后,它下降到 6 毫秒。
Nvidia visual profiler 显示内核在第一分钟内几乎一直处于空闲状态。
我不知道是什么导致了第一分钟之前|之后的性能变化。感谢您的帮助。
最佳答案
ArrayFire 在运行时使用 JIT 编译来融合对函数的多次调用。因此,当您执行加法或任何其他元素方面的操作时,ArrayFire 将创建一个自定义内核并执行该内核。当您第一次生成这个内核时,这会产生一些开销,但这些内核会被缓存,不需要编译额外的调用。通常,在不需要额外的编译之前,它应该只需要几次迭代。奇怪的是,即使在 60 次左右的迭代之后,内核仍然很慢。
JIT 内核使用基于内存和内核大小的内部启发式方法进行评估。也许您的应用程序没有以最佳方式触发内核并导致额外的内核编译。您可以通过对变量调用 eval 函数来强制执行评估来解决此问题。这是一个人为的例子:
array a = randu(10, 10);
array b = randu(10, 10);
for(int i = 0; i < 100; i++) {
a += b / 4;
b *= i;
eval(a, b);
}
在这里,您将在每次迭代中评估变量 a 和 b 的 JIT 树。这将在每次迭代中重用相同的内核,而不是为不同的多次迭代创建内核。
需要注意的是元素方面,一些条件函数(如 select 和 shift)是 JIT 的。其他函数在使用之前强制评估它们的参数。此外,如果您过于频繁地评估,您将降低应用程序的性能。
关于c++ - ArrayFire CUDA 应用程序在第一分钟内非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50242141/
如何在 af::array 中创建一个简单的行列式? 尝试在 af::array x 中使用:af::det(x)检测(x)x.det() 并且不起作用。 有人可以帮助我吗? error: no m
对本应简单的事物感到困惑。花了一些时间尝试调试它,但并没有走得太远。如果有人能帮助我,我将不胜感激。 我正在尝试通过指定此 function 中指定的值/列/行三元组来在 arrayfire 中定义一
我正在使用 arrayfire crate 以使用 af::load_image 打开图像。这为我提供了一个 f32 数组,我可以对其进行一些处理。完成后,我想使用 af::save_image 将其
我尝试翻转大小为 [249 1 50 20] 的矩阵,这是代码: array flipped_delta = flip(delta, 0); 我得到以下异常: Unhandled exception
我正在尝试使用 arrayFire python ( https://github.com/arrayfire/arrayfire-python ) 进行多 GPU 编程。 但是,当我尝试将其与并发
我正在尝试使用 GFOR 结构,但我什至不能让它用于基本的东西。 我怀疑 GFOR 循环不适用于线性索引,对吗? 这里有一些不起作用的代码示例 af::array x(100, 200); af::a
我最近在 GTC 上看到了 arrayfire 演示,我想我会尝试一下。以下是我在尝试使用它时遇到的一些问题。我在 Windows 7 系统上运行 Visual Studio 2013,使用来自 AM
我在从主机数据初始化 arrayfire 数组时遇到问题。 以下代码不会为我链接: constexp int mNumEigenInfos = 100; std::complex mEigenVect
我下载了 ArrayFire 库的免费版本。我试图用它来测试矩阵乘法。但是我得到了一堆 undefined reference ,例如 matrixdata.cpp:(.text+0x19e5): u
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
有没有办法在同一个位置多次更改数组? 当我这样做时: float a[] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 }; array A(6, a, afHost); af_p
我试图在循环中迭代地从 ArrayFire 数组 (af::array) 中删除元素。假设我有: af::array arr = af::range(af::dim4(4), -1, u32) + 1
在 ArrayFire 中使用固定内存时,性能变慢。 我已经尝试了各种创建固定内存和从中创建数组的方法,例如。 cudaMallocHost。使用带 cudaMemcpy 的 cudaMallocHo
我通过调用简单的 arrayfire 构造函数遇到了段错误。 #include int main(){ af_array a; int N = 10; dim_t dims
我最近在我的 Ubuntu 12.04 上安装了 ArrayFire 2.1。我想将它与 Python 一起使用,可以吗?我试过 ArrayFire_Python但它是不完整的,它不包括rotate等
我有一个关于在 ArrayFire for Python 中使用多个主机线程的新手问题。我们目前拥有高度并行的仅 CPU 代码,使用 Open MPI 和 mpi4py 进行并行化。每个 CPU 线程
假设我有一个 stl::array foo这是 Column-Major 格式 arrayfire 数组的线性化 STL 吊坠,例如af::array bar = af::array(4,3,2, 1
我正在使用在 Windows 10 + Nvidia Gtx 970 上运行的 ArrayFire 编写测试程序。该程序用于使用 SGD 求解器训练神经网络。因此,主要计算是更新网络参数的迭代。迭代在
我正试图在 ArrayFire 中饱和我的数组。我希望所有大于 0.75 的值都饱和到 1.0,所有小于 0.25 的值都饱和到 0.0。我正在使用以下表达式。 a(a > 0.75) = 1.0;
我想在 ArrayFire 中创建虚数单位,但我不能。我可以从实数矩阵构造一个复数矩阵,但这不是纯虚数。也许我可以使用 this page 中的函数 af_cplx2 .我想到了以下几点: af_ar
我是一名优秀的程序员,十分优秀!