【问题标题】:get_global_size(0) crashes the controllerget_global_size(0) 使控制器崩溃
【发布时间】:2016-06-19 05:22:44
【问题描述】:

每个人。

我得到了这个内核:

__kernel void FuncionCL(__global char* in, __global char* out, __global int* S2)
{
    __private int op1, op2, op3;
    __private int C;
    __private uint WorkDim, C2;
    op1 = 1;
    op2 = 2;
    WorkDim = get_global_size(0);
    __private int ID;
    ID = get_global_id(0);
    for(C = 0; C < 1000000; C++)
    {
        for(C2 = ID; C2 < 1000; C2 += WorkDim)
        {
            op3 = op1 + op2;
        }
    }
    out[0] = 90;
    out[1] = 89;
    *S2 = (int) WorkDim;
}

不仅应用程序崩溃,图形控制器也崩溃。我更改常量值“16”的增量(get_global_size() 函数返回)然后代码运行正常。有什么问题?

如果我运行代码:

WorkDim = 16;

在第 8 行,而不是:

WorkDim = get_global_size(0);

代码运行速度快了 400 倍,这就是问题所在。为什么值相同?

**编辑:**好吧,现在我知道为什么了,代码这么慢而且有多种原因:

1.- 入住率。

2.- 所有线程在第一个循环中执行相同的迭代,正确的代码如下所示:

__kernel void FuncionCL(__global char* in, __global char* out, __global int* S2) { __private int op1,op2,op3; __private int C; __private uint WorkDim, C2; 操作1 = 1; op2 = 2; WorkDim = get_global_size(0); __private int ID; ID = get_global_id(0); for(C = ID; C

现在我的代码在 GPU 上的运行速度是 CPU 的 6.1 倍。

【问题讨论】:

  • 它是立即崩溃还是在一段时间后(如 5 到 10 秒)崩溃?如果是后者,则是操作系统 GPU 看门狗定时器正在重置 GPU,因为内核花费的时间太长。理想情况下,您希望内核运行时间少于 50 毫秒,否则它们会开始影响系统响应能力(因为它们也用于 UI 绘制等)。
  • 感谢您的回答。是的,它在 5 秒后崩溃。但问题是为什么?看起来 get_global_size(0) 返回 0 并且循环永远不会结束,但是,如果我使用常量值增量而不是 WorkDim 中的值,内核会返回 '16'(get_global_size(0) 预期值)。

标签: opencl


【解决方案1】:

那里的每个项目都在做 1000000*1000 = 1Gop。太多了,需要太长时间才能做到这一点,并且驱动程序会重新启动 GPU。 (我猜在你的例子中全局大小是 1)

用这么少的工作项来运行一个 CL 内核完全是一种资源浪费,它会使 GPU 进行几乎串行的计算并且花费的时间太长。

新 GPU 中至少需要 1024 个全局项目才能充分利用其资源。

编辑:当它具有静态值时,编译器可能会优化循环。因此提供了“惊人的”加速。

【讨论】:

  • 好的,我知道 1Gflop 太多了,但是如果我使用循环“WorkDim = 16;”运行代码它的运行速度比“WorkDim = get_global_size(0)”快太多。我一直在以 100*1000 次迭代运行代码,两个代码之间的时间差大约慢 400 倍,返回的值是“get_global_size(0)”。现在,我只使用 16 个工作项运行此代码的原因是因为我有一个 GeForce 210(16 个 CUDA 内核)。
  • 你应该这样设计。您应该根据需要启动尽可能多的项目,并让设备尽可能地并行化。仅使用 16 个项目并不能使用您的所有设备(每个 CUDA 核心可以在现代设备中启动多达多个项目,即 64 个或更多)。
  • 硬编码提高性能的原因,很容易猜测编译器的优化。你没有保存循环的任何有用数据,如果循环参数是可变的,那么它就不能被优化,但如果它是静态的,编译器就会简单地删除整个循环。
  • 非常感谢您,DarkZeros。实际上,此时我正在使用该代码,并且我的想法相同,因为无论循环的大小如何,结果都是相同的。所以,现在我得到了我的答案。再次,非常感谢。
猜你喜欢
  • 2022-01-04
  • 2017-07-23
  • 1970-01-01
  • 2011-01-21
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多