Julia-Speicherzuweisung für die Addition von zwei Matrizen an Ort und Stelle

8

Ich bin gespannt, warum Julias Implementierung der Matrix-Addition eine Kopie zu machen scheint. Hier ein Beispiel:

%Vor%

Die Menge des zugewiesenen Speichers entspricht in etwa dem Speicher, der für eine Matrix dieser Dimensionen benötigt wird.

Es sieht so aus, als ob zur Verarbeitung von foo2 + foo3 Speicher reserviert wird, um das Ergebnis zu speichern, und dann wird foo1 als Referenz zugewiesen.

Bedeutet dies, dass wir für die meisten Operationen der linearen Algebra BLAS- und LAPACK-Funktionen direkt aufrufen müssen, um die Dinge an Ort und Stelle zu erledigen?

    
Lindon 17.02.2016, 19:19
quelle

2 Antworten

13

Um zu verstehen, was hier vor sich geht, wollen wir überlegen, was foo1 = foo2 + foo3 tatsächlich tut.

  • Zuerst wird foo2 + foo3 ausgewertet. Dazu wird ein neues temporäres Array zugewiesen, das die Ausgabe
  • enthält
  • Dann wird der Name foo1 an dieses neue temporäre Array gebunden, wodurch alle Anstrengungen rückgängig gemacht werden, die Sie vorgenommen haben, um das Ausgabe-Array vorzubelegen.

Kurz gesagt, Sie sehen, dass die Speichernutzung ungefähr der des resultierenden Arrays entspricht, da die Routine tatsächlich einen neuen Speicher für ein Array dieser Größe zuweist.

Hier sind einige Alternativen:

  • schreibe eine Schleife
  • benutze broadcast!
  • Wir könnten versuchen, copy!(foo1, foo2+foo3) zu machen, und dann wird das Array, das Sie vorher zugewiesen haben, gefüllt, aber es wird immer noch das temporäre (siehe unten)
  • zuweisen
  • Die ursprüngliche Version hier gepostet

Hier ist ein Code für diese 4 Fälle

%Vor%

Lassen Sie uns jetzt diese Funktionen

%Vor%

Sie können sehen, dass with_loop! und broadcast! ungefähr dasselbe tun und beide sind viel schneller und effizienter als die anderen. with_copy! und original sind beide langsamer und benötigen mehr Speicher.

Um Inplace-Operationen zu machen, würde ich generell empfehlen, mit einer Schleife zu beginnen

    
spencerlyon2 17.02.2016 20:08
quelle
2

Lesen Sie zuerst @ spencerlyon2's Antwort. Ein anderer Ansatz besteht darin, Dahua Lins Paket Devectorize.jl zu verwenden. Es definiert das Makro @devec , das die Übersetzung von Vektor (Array) -Ausdrücken in einen Schleifencode automatisiert.

In diesem Beispiel definieren wir with_devec!(foo1,foo2,foo3) wie folgt,

%Vor%

Das Ausführen des Benchmarks führt zu den vier Zuordnungsresultaten.

    
Dan Getz 17.02.2016 22:39
quelle

Tags und Links