【问题标题】:cupy indexing is slowCupy 索引很慢
【发布时间】:2020-05-02 21:24:46
【问题描述】:

我正在尝试对大小为 16000 的大型 cupy 数组执行操作。我发现诸如加法之类的数学运算非常快,但使用布尔掩码进行索引相对较慢。例如以下代码:

import cupy as cp
arr = cp.random.normal(0, 1, 16000)
%timeit arr * 5
%timeit arr > 0.4
%timeit arr[arr > 0.4] = 0

给我输出:

28 µs ± 950 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
26.5 µs ± 1.61 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
104 µs ± 2.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

为什么最终索引速度至少慢了一倍?我假设乘法应该比设置数组元素慢。

更新:这不适用于 numpy 索引。将cupy数组改为numpy,我得到:

6.71 µs ± 373 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
4.42 µs ± 56.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
5.39 µs ± 29.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

【问题讨论】:

    标签: python-3.x performance cupy


    【解决方案1】:

    在第三种情况下,cupy 正在通过一系列操作组合结果:cupy_greatercupy_copyinclusive_scan_kernelinclusive_scan_kerneladd_scan_blocked_sum_kernelCUDA memcpy DtoH(可能提供数字需要设置为零的元素),CUDA memset(可能将数组设置为零),最后是cupy_scatter_update_mask(可能将零分散到正确的位置)。

    这是一个比arr*5 复杂得多的序列,arr*5 似乎在后台运行单个cupy_multiply。使用cupy user-defined kernel 可能会做得更好:

    import cupy as cp
    clamp_generic = cp.ElementwiseKernel(
            'T x, T c',
            'T y',
            'y = (y > x)?c:y',
            'clamp_generic')
    arr = cp.random.normal(0, 1, 16000)
    clamp_generic(0.4, 0, arr)
    

    【讨论】:

    • 谢谢你——解决了。在 'clamp_generic' 上运行 'timeit' 每个循环只给我 6.12 µs ± 149 ns。
    猜你喜欢
    • 2016-12-04
    • 2014-09-24
    • 2018-12-13
    • 2020-05-05
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    相关资源
    最近更新 更多