python - schnelle Matrixmultiplikation und -reduktion während der Arbeit in Memmaps und CPU

Hi, ich habe Probleme mit der schnellen Matrixmultiplikation, Addition, Funktionsüberschreibung und Summierung mit Achsenreduktion und der Arbeit in numpy.memmaps über CPU ohne RAM (glaube ich). Nur wenn ich numexpr benutze, kann ich vermeiden, ein Array aus einem Punkt zu erstellen.

For example:

a=np.require(np.memmap('a.npy',mode='w+',order='C',dtype=np.float64,shape=(10,1)),requirements=['O']) 
b=np.memmap('b.npy',mode='w+',order='C',dtype=np.float64,shape=(1,5))
c=np.memmap('c.npy',mode='w+',order='C',dtype=np.float64,shape=(1,5))
#func -> some method, like i.e. sin()
#in numexpr it will be simple
ne.evaluate('sum(func(b*a+c),axis=1)')
#in numpy with einsum it will have to be with creating additional out-of-dot handling array
d=np.require(np.memmap('d.npy',mode='w+',order='C',dtype=np.float64,shape=(10,5)),requirements=['O']) 

np.einsum('ij,kj->ki',b,a,out=d)
d+=c
func(d,out=d)
np.einsum('ij->i',d,out=c)

Ist es überhaupt möglich, mit CPU ohne RAM schneller zu arbeiten als mit numexpr? Wie wäre es mit Cython + FORTRAN Lapack oder Blass? Irgendwelche Tipps oder Tricks sind willkommen! Vielen Dank für jede Hilfe!

EDITED INFO: Übrigens, ich arbeite an einem Laptop mit Intel Core2Duo t9300 CPU, 2,7 GB RAM (nur von 4 GB, aufgrund eines BIOS-Problems), SSD 250 GB, alter Intel GPU. Aufgrund des geringen Arbeitsspeichers, der hauptsächlich von Firefox mit einigen Addons verwendet wird, bleibt nicht viel für die Codierung übrig. Deshalb vermeide ich die Verwendung von xD.

Und ich habe das Gefühl, fortgeschritten zu sein (Schritt 1/1000), wenn ich im Moment nicht weiß, wie Code auf Hardware funktioniert - ich vermute es nur (daher können einige meiner Denkfehler auftreten xD). .

BEARBEITEN Ich habe in Cython einen Code zum Berechnen von Sinuswellen mit numexpr und cython prange for-loop erstellt.

Pulsationsdaten (für om, eps, Spectra, Amplitude) werden in OM numpy.memmap und Zeitdaten (t, z) in TI numpy.memmap gespeichert. OM hat eine Form wie (4,1,2500) und TI hat eine Form wie (2,1,5e + 5,1) - ich brauche sie nur in dieser Form.

cdef inline void sine_wave_numexpr(OM,TI,int num_of_threads):

    cdef long m,n=10
    cdef Py_ssize_t s=TI.shape[2]/n
    cdef str ex_sine_wave=r'sum(A*sin(om*ti+eps),axis=1)'
    cdef dict dct={'A':OM[3],'om':OM[0],'eps':OM[2]}
    for m in range(n):
        sl=slice(s*m,s*(m+1))
        dct['ti']=TI[0,0,sl]
        evaluate(ex_sine_wave,
                    global_dict=dct,
                    out=TI[1,0,sl,0])
cdef inline void sine_wave_cython(double[:,:,::1]OM,double[:,:,:,::1]TI,int num_of_threads):
    cdef int i,j
    cdef Py_ssize_t n,m
    cdef double t,A,om,eps
    n=OM.shape[2]
    m=TI.shape[2]
    for i in prange(m,nogil=True,num_threads=num_of_threads):
        t=TI[0,0,i,0]
        for j in prange(n,num_threads=num_of_threads):
            A=OM[3,0,j]
            om=OM[0,0,j]
            eps=OM[2,0,j]
            TI[1,0,i,0]+=A*sin(om*t+eps)

cpdef inline void wave_elevation(double dom,OM,TI,int num_of_threads, str method='cython'):
    cdef int ni
    cdef double i,j
    cdef Py_ssize_t shape=OM.shape[2]
    numexpr_threads(num_of_threads)
    OM[2,0]=2.*np.random.standard_normal(shape)
    evaluate('sqrt(dom*2*S)',out=OM[3],
            local_dict={'dom':dom,'S':OM[1]})
    if method=='cython':
        sine_wave_cython(OM,TI,num_of_threads)
    elif method=='numexpr':
        sine_wave_numexpr(OM,TI,num_of_threads)
    TI.shape=TI.shape[:3]

Ich fange gerade mit Cython an, daher kann es sein, dass es nicht gut optimiert ist. Derzeit dauert Code mit Prange genauso lange wie mit Numexpr (RAM-Auslastung beträgt 100 MB für den gesamten Code mit diesem Teil, CPU ist 50%, SSD ist niedrig - die Berechnungszeit beträgt 1 bis 2 Minuten). Ich habe es mit Speicheransichten versucht, aber das hat einige lokale Kopien erstellt und den Arbeitsspeicher mit der Zeit genutzt. Ich muss Stufe 3/1000 für Fortgeschrittene sein, um zu verstehen, wie man mit Speicheransichten arbeitet.

Antworten auf die Frage(0)

Ihre Antwort auf die Frage