You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让np.multiply使用多个CPU核心?

解决numpy逐元素乘法无法利用多核心的问题

numpy的np.multiply(或*运算符)默认是单线程执行的,这是因为它不属于BLAS库优化的核心线性代数操作范畴——BLAS主要针对矩阵乘法、点积这类计算密集型运算,而逐元素乘法本质是内存绑定的简单操作,numpy原生没有为它实现多线程并行逻辑,这就是你看到仅用1核的原因,调整BLAS环境变量没用也正是因为这个操作根本不调用BLAS接口。

下面是几个可行的多核心优化方案:

1. 用Numba手动实现并行

Numba可以通过JIT编译为逐元素运算添加CPU并行支持,尤其适合三维数组和广播场景,代码改动很小:

import numpy as np
from numba import njit, prange

@njit(parallel=True)
def parallel_broadcast_multiply(x, y):
    # 自动适配广播后的输出形状
    out_shape = np.broadcast_shapes(x.shape, y.shape)
    out = np.empty(out_shape, dtype=x.dtype)
    # 并行遍历最外层维度,Numba会自动处理内存访问和广播逻辑
    for i in prange(out_shape[0]):
        for j in range(out_shape[1]):
            out[i, j] = x[i, j] * y[i, j]
    return out

# 测试三维广播场景
x = np.random.rand(200, 200, 1000)
y = np.random.rand(200, 1, 1000)
z = parallel_broadcast_multiply(x, y)

如果是更复杂的广播规则,Numba的prange也能轻松适配,只要确保循环逻辑覆盖所有元素即可。

2. 用Dask数组实现分布式并行

如果你的数组规模极大,Dask可以将数组分片后利用多核心并行处理,代码和numpy几乎兼容:

import dask.array as da

# 将numpy数组转为Dask数组,chunks参数控制分片大小(根据内存情况调整)
x_da = da.from_array(x, chunks=(50, 50, 250))
y_da = da.from_array(y, chunks=(50, 1, 250))
# 逐元素乘法自动并行执行
z_da = x_da * y_da
# 触发计算并获取结果
z = z_da.compute()

3. 利用GPU加速(如果有硬件支持)

如果你的机器有NVIDIA GPU,用CuPy替代numpy可以自动利用GPU并行,逐元素运算的速度会远快于CPU多核心:

import cupy as cp

# 代码和numpy完全一致,只是把np换成cp
x = cp.random.rand(200, 200, 1000)
y = cp.random.rand(200, 1, 1000)
z = x * y
# 如需转回numpy数组
z_np = cp.asnumpy(z)

额外优化:优化内存布局

如果你的三维数组是广播产生的非连续数组,先转为连续数组可以提升单线程(以及并行)的执行效率:

x = np.ascontiguousarray(x)
y = np.ascontiguousarray(y)

需要注意的是,逐元素运算属于内存绑定操作,并行加速比不会完全和核心数成正比,实际收益取决于你的内存带宽和数组规模,但上述方法都能有效利用你的40核心资源。

内容的提问来源于stack exchange,提问作者ArtPe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:06:25