python多进程与np数组与talib计算金融指标问题

cpu24核心笔记本电脑2个内存条16g 3200m x2,用1核运行速度是50+每秒it。用10个应该是500+。但是只有170+,我尝试从1核到10核测试,发现到3核后就不是成倍增加了,后面增加核心速度变快的很少。是不是内存速度瓶颈。

 with Pool(processes=workers) as pool:  #
            # 使用并行批量获得'list'>
            results = pool.imap_unordered(
                # 先测试单个核心一秒多少个,用于设置chunksize参数
                partial(calculate_by_one_loop, duo_lock=duo_lock), para_list, chunksize=50)
            # 显示进度条
            for i, result in tqdm(enumerate(results),
                                  total=total, desc='总任务进度', mininterval=1, maxinterval=1):
                df_list.append(result)

其中calculate_by_one_loop是目标函数,里面就执行np数组的计算

x = talib.SMA(close, timeperiod=10)

@jit('float64[:,:](float64[:], float64[:], float64[:], float64[:])')
def numpy_chaoji_qushi(atr, close, high, low):
    """
    超级趋势计算

    :param atr: 真实波动幅度
    :param close: 收盘
    :param high: 最高
    :param low: 最低
    :return: 超级趋势
    """

    src = np.full_like(close, np.nan, dtype='float64')  # 生成空白的数组,结构和close一样
    up = np.full_like(close, np.nan, dtype='float64')  # 生成空白的数组,结构和close一样

    dn = np.full_like(close, np.nan, dtype='float64')  # 生成空白的数组,结构和close一样

    for i in range(close.shape[0]):
        # 价格源hlc3
        src[i] = (close[i] + high[i] + low[i]) / 3
        # 计算超级趋势指标的上涨趋势线
        up[i] = src[i] - atr[i]
        # 过去的收盘价 大于 up[1]
        if close[i - 1] > up[i - 1]:
            # up就等于 up 与up1 中最大的
            up[i] = max(up[i], up[i - 1])
        else:  # 不是就返回up自己
            up[i] = up[i]
        # 计算超级趋势指标的下跌趋势线
        dn[i] = src[i] + atr[i]
        # 过去的收盘价 大于 up[1]
        if close[i - 1] < dn[i - 1]:
            # up就等于 up 与up1 中最大的
            dn[i] = min(dn[i], dn[i - 1])
        else:  # 不是就返回up自己
            dn[i] = dn[i]

    return np.vstack((up, dn))

很多这种使用talib的代码,基本用5列数组会生成几十上百列。再循环判断逻辑。我测试过单次计算50多ms
之前我是使用pandas的df
例如:df['x'] = talib.SMA(df['close'], timeperiod=10)
后面改成np数组,没使用一点df。速度提升了一点点。我重新写了一个只计算数学问题的程序,速度是随着进程数成倍增加的。我20核全开速度就比1核快将近20倍。所以我怀疑内存速度,但是我不知道怎么优化,已经从df数据改成np数组了。每计算一个金融指标(均线这些)就有一个单独的变量存起来。我看别人用服务器cpu和主板和内存,开几十上百个线程,速度飞快
帮我优化一下

可能是内存速度瓶颈,也可能是其他因素导致的。在多核并行计算中,除了CPU核心数和内存大小外,还有很多因素会影响计算速度,比如硬盘速度、缓存大小、算法复杂度等等。因此,要想准确分析速度瓶颈,需要对整个系统进行综合评估,包括硬件和软件方面。

另外,从1核到10核速度增加不是成倍增加,这也是正常现象。多核并行计算的速度增加并不是线性的,随着核心数的增加,计算效率会逐渐降低,因为多核并行计算需要更多的协调和同步,而这些操作也需要消耗一定的时间和资源。

总之,要想提高多核并行计算的速度,需要从多个方面入手,包括优化算法、提高硬件性能、合理调整系统参数等等。

关于您提出的python多进程使用np数组速度的问题,内存的大小是会影响执行速度,所以就需要在可用的内存大小下最大化CPU的执行速度,如果您的工作是numpy密集型的,您可以通过使用多线程而不是多处理来加快它的速度。代码可以参考该网站上的回答:https://stackoverflow.com/questions/38666078/fast-queue-of-read-only-numpy-arrays/38775513#38775513

根据你提供的信息,可以初步推断出内存速度可能不是瓶颈,因为你已经使用了高速的DDR4内存,而且也没有提到内存使用率的问题。

可能的瓶颈可能来自于以下几个方面:

计算密集型任务的并行度限制:在使用并行计算时,很重要的一点是任务的并行度必须足够高,否则增加更多的核心并不会带来明显的速度提升。你可以尝试使用一些工具来测量你的任务的并行度,例如Intel VTune、Python的multiprocessing模块等等。如果发现任务的并行度已经很高了,那么增加更多的核心就不会带来明显的速度提升。

Python的全局解释器锁(GIL):Python的GIL限制了同一时刻只能有一个线程执行Python代码,这就导致了在使用多线程时,只能利用到单个核心的计算能力,而不能真正意义上的并行计算。这个问题可以通过使用多进程来解决,因为多进程可以利用多个CPU核心的计算能力,而且进程之间不受GIL的限制。

数据结构和算法的优化:你的任务中涉及到大量的数组计算和循环判断逻辑,这些都是计算密集型的操作。在这种情况下,使用NumPy和Numba等库进行向量化和JIT编译可以显著提升代码的运行效率。此外,还可以考虑一些优化算法,例如分治法、并行算法等等,来降低计算复杂度,提升代码运行速度。

硬件优化:如果以上优化措施都已经尝试过了,但是速度还是无法满足需求,那么可能需要考虑升级硬件,例如更换更高性能的CPU、使用更多的内存等等,来提升计算能力。

总的来说,针对你的问题,可以先使用一些工具来测量任务的并行度和性能瓶颈,然后从算法和代码结构、库的使用、硬件升级等方面进行优化。