SSD und mmap: kann mir jemand das Verhalten erklären?



  • /edit: oops das sollte in Rund um die Programmierung...

    Willkommen in Otzes Welt der komichen Algorithmen.

    Ich Benchmarke hier gerade 2 Implementierungen eines Algorithmus gegeneinander, welche auf mmap basieren. Im Kern habe ich eine große Matrix die extrem teuer zu berechnen ist. Ich brauche bei jeder iteration des algorithmus immer nur 2 Zeilen der Matrix. Da die Matrix groß ist, habe ich mich dazu entschieden, sie mithilfe von mmap in eine Datei zu schreiben. Nun Benchmarke ich was besser ist:

    1. Berechne die komplette Matrix als Block bevor der Algorithmus startet
    2. Berechne die Matrixzeilen erst wenn wirklich angefordert

    1. hat den Vorteil dass es bis zu Faktor 6 schneller ist, die Matrix so zu berechnen und 2. hat den Vorteil dass ich nicht alle Matrixzeilen brauche(ich aber nicht weiß welche und wieviel). Desweiteren kann ich die wirklich benötigten Matrixzeilen dicht in der Datei speichern, wodurch random access eventuell weniger schlimm ist.

    In meinem Test besteht eine Matrixzeile aus 100.000 floats = ~400kb. Ich habe ungefähr 4.5GB cache welcher für mmap zur Verfügung steht.

    Der Algorithmus löst für ein gegebenes Set von Hyperparametern (C) ein quadratisches Problem und ich messe die Laufzeit. Dabei erhebe ich die Zeit die im Solver verbracht wird(solver_time) und die Gesamtlaufzeit(die auch die Zeit zum einmaligen Vorberchnen der Matrix umfasst). Die Matrix ist für alle C gleich, weswegen ich die Werte nur einmal berechne.

    Zuerst habe ich das Experiment auf einer normalen Festplatte durchlaufen lassen:

    # vorberechnet(1.)
    # C   cumulated_time solver_time
    0.1 3577.87 2253.6
    1   8762.66 5184.79
    10  13003.9 4241.22
    #on demand(2.)
    # C   cumulated_time solver_time
    0.1  9313.23 9313.23
    1    12924.2 3610.93
    10   16168.7 3244.48
    

    Das Ergebnis war die erwartet: die vorberechnete Matrix gewinnt extrem durch die Blockberechnung hat aber dann hinterher höhere Kosten für den Lookup gegenüber dem Ansatz der nur on demand berechnet.

    Meine Vorhersage bei der SSD war:der Ansatz der vorberchnet sollte stärker gewinnen, weil die random accesses nicht mehr so teuer sind. Hier die Resultate:

    # vorberechnet(1.)
    # C   cumulated_time solver_time
    0.1  3361.43 2059.49
    1    7878.24 4516.81
    10   12293   4414.74
    #on demand(2.)
    # C   cumulated_time solver_time
    0.1 9130.83 9130.83
    1   10220.6 1089.8
    10  11069.2 848.616
    

    Und irgendwie...ist das völlig anders als erwartet. Irgendjemand eine Idee?Die Algorithmen verhalten sich komplett identisch bis auf diesen Lookup.



  • kann es sein dass die mit mmap in den virtuellen Speicher gemappte Datei sich tatsächlich komplett im RAM befinden?
    Bei einem 64bit System mit genug RAM durchaus möglich!?

    Das würde ja erklären, warum das Speichermedium ziemlich egal ist.

    Die im Page Cache liegenden Daten werden dann in einem Kernel Thread im Hintergrund immer wieder zurück in die Datei auf der Festplatte geschrieben, wenn es Änderungen gibt.



  • Neee. Die Datei ist 40GB groß und ich hab 8GB RAM. Das ist es also leider nicht.
    Selbst wenn man davon ausgeht, dass es in der zweiten Implementierung so sein könnte, dass der beenutzbare Teil in den Ram passt, dann müssten die Unterschiede zwischen den beiden Verfahren schon im ersten Test sehr deutlich messbar sein.


Log in to reply