Multithreading, Speicher ans OS retournieren.
-
Tachyon schrieb:
314159265358979 schrieb:
Führ halt nen Scope ein, damit das thread-Objekt auch vor der Schleife aufgeräumt wird...
Das sagte ich doch schon...

OK, gleicher Effekt.
#include <stdio.h> #include <iostream> #include <boost/thread.hpp> using namespace std; void fun() { cout<<"Hi, I'm the thread"<<endl; }; int main(int ,char**) { #if 0 fun(); #else { boost::thread a(fun); a.join(); } #endif cout<<"Thread finished"<<endl; while(1); return 0; }
-
Die zusätzlichen 12.5 MB gehen sicher nicht im Thread-Objekt drauf, d.h. ob new() oder nicht wird hier keine Rolle spielen.
Ich würde eher davon ausgehen dass die Heap-Implementierung den frei gewordenen Speicher nicht ans OS zurückgibt. Entweder weil sie es nicht kann (z.B. wegen Fragmentierung), oder weil sie den Speicher nur dann ans OS zurückgibt, wenn eine bestimmte Grenze überschritten wird. Was für die meisten Applikationen ja auch Sinn macht. Die Heap-Performance würde arg leiden, wenn jede 4K Seite sofort ans OS zurückgegeben würde - dann müsste ja dauernd neuer Speicher angefordert und wieder freigegeben werden.
Ob es ein echtes Memory-Leak gibt, kann man am einfachsten feststellen, indem man ein geeignetes Tool verwendet. Ich denke Valgrind sollte das können (hab's aber selbst noch nie verwendet, da ich für Windows programmiere und wir BoundsChecker dafür verwenden).
Nochwas: es ist denkbar, dass eine CRT/SCL Implementierung bestimmte Datenstrukturen die für thread-safety nötig sind erst erzeugt/initialisiert, wenn der erste "nicht-main" Thread bestimmte Funktionen aufruft. Und in Boost.Thread gibt es definitiv einige Datenstrukturen die "lazy" Initialisiert werden, d.h. erst bei Erzeugung des ersten Boost.Thread.
Ich denke folgendes Testprogramm wäre eher sinnvoll:
#include <stdio.h> #include <iostream> #include <boost/thread.hpp> using namespace std; void fun() { cout<<"Hi, I'm the thread"<<endl; }; int main(int ,char**) { cout<<"Hi, I'm main()"<<endl; { boost::thread a(fun); a.join(); } #if 0 fun(); #else { boost::thread b(fun); b.join(); } #endif cout<<"Thread finished"<<endl; while(1); return 0; }Hier dürfte mMn. kein grosser Unterschied mehr bestehen. Wenn doch, dann könnte man wirklich mal auf die Suche gehen ob hier nicht irgendwas verkehrt läuft.
-
um mit "top" den Speicherbedarf
Nutze
valgrind,topbitte nicht
-
hustbaer schrieb:
Die zusätzlichen 12.5 MB gehen sicher nicht im Thread-Objekt drauf, d.h. ob new() oder nicht wird hier keine Rolle spielen.
Ich würde eher davon ausgehen dass die Heap-Implementierung den frei gewordenen Speicher nicht ans OS zurückgibt.
Ich glaube auch, daß der Speicher aus Effizienzgründen nicht gleich retourniert
wird. Macht nur das Debuggen schwieriger. Valgrind kenne und verwende ich sehr
gerne. Nur ist meine Anwendung numerisch kritisch, und da nicht alle Rundungs-
Modi in Valgrind implementiert sind, läuft das nicht. Unser Testprogramm geht
aber. Endlosschleife entfernt, und dann:==25904== Memcheck, a memory error detector ==25904== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==25904== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info ==25904== Command: ./justATest ==25904== Hi, I'm main() Hi, I'm the thread Hi, I'm the thread Thread finished ==25904== ==25904== HEAP SUMMARY: ==25904== in use at exit: 8 bytes in 1 blocks ==25904== total heap usage: 7 allocs, 6 frees, 808 bytes allocated ==25904== ==25904== 8 bytes in 1 blocks are still reachable in loss record 1 of 1 ==25904== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) ==25904== by 0x4E424C9: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1) ==25904== by 0x4E3B3BF: ??? (in /usr/lib/libboost_thread.so.1.46.1) ==25904== by 0x4E3B688: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1) ==25904== by 0x4E3CDFA: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1) ==25904== by 0x402D4E: main (in /home/geom/repo/dev/test_all/test_mt3/justATest) ==25904== ==25904== LEAK SUMMARY: ==25904== definitely lost: 0 bytes in 0 blocks ==25904== indirectly lost: 0 bytes in 0 blocks ==25904== possibly lost: 0 bytes in 0 blocks ==25904== still reachable: 8 bytes in 1 blocks ==25904== suppressed: 0 bytes in 0 blocks ==25904== ==25904== For counts of detected and suppressed errors, rerun with: -v ==25904== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)Interessant ist, woher die Still-Reachable kommen.
-
Ich glaube auch, daß der Speicher aus Effizienzgründen nicht gleich retourniert wird.
Ja, weil wenn es gleich danach wieder was vom Programm angefordert wird, fuehlt sich das Betriebssystem verarscht.
Nur ist meine Anwendung numerisch kritisch, und da nicht alle Rundungs-
Modi in Valgrind implementiert sind, läuft das nicht.Naja, Speicher hat normalerweise nichts mit Rundungen zu tun.
-
knivil schrieb:
Naja, Speicher hat normalerweise nichts mit Rundungen zu tun.
Bei Rundungsfehlern werden Prädikate falsch evauliert und das Programm haut
es in Valgrind auf.
-
-
memr schrieb:
Bei Rundungsfehlern werden Prädikate falsch evauliert
Valgrind fuehrt dein Programm so aus, wie du es kompiliert hast. Klar kann das Verhalten von Debug zu Release unterschiedlich sein, aber das hat mit Valgrind nichts zu tun. Du kannst Valgrind auch mit der Releaseversion benutzen. Du erhaelts immer noch eine Zusammenfassung.
und das Programm haut es in Valgrind auf.
Aeh, und das heisst? Bitte auf Deutsch.
-
knivil schrieb:
memr schrieb:
Bei Rundungsfehlern werden Prädikate falsch evauliert
Valgrind fuehrt dein Programm so aus, wie du es kompiliert hast. Klar kann das Verhalten von Debug zu Release unterschiedlich sein, aber das hat mit Valgrind nichts zu tun. Du kannst Valgrind auch mit der Releaseversion benutzen. Du erhaelts immer noch eine Zusammenfassung.
und das Programm haut es in Valgrind auf.
Aeh, und das heisst? Bitte auf Deutsch.
In der rechnerischen Geometrie ist es häufig erforderlich, die Vorzeichen von
Determinanten zu ermitteln. Beispielsweise, um festzustellen, ob ein Punkt
oberhalb, unterhalb oder genau in einer Ebene liegt. Ist die Determinante nahe
Null, so kann wegen der begrenzten Rechengenauigkeit eine falsche Antwort
berechnet werden, was den Algorithmus in einen falschen Zweig führt ->
Endlosschleife/Segfault/Assertion. Typischerweise sind viele tausend solcher
Tests erforderlich, so daß das Problem nicht nur theoretischer Natur ist,
sondern eigentlich immer schlagend wird. Es gibt Methoden, um die Problematik
zu handhaben, aber die setzen korrekte Rundung voraus, die in Valgrind nicht
vorliegt. Deshalb laufen dort solche Programme meist nicht.
-
Ich weiss um die Numerik dahinter Bescheid, nur kann ich den Zusammenhang mit Valgrind nicht herstellen. Valgrind installiert Hooks fuer free und malloc und fuehrt dein Programm aus und tracked deinen Speicher. Dabei kann ich keinen Einfluss auf numerische Berechnungen feststellen. Wo rundet Valgrind?
-
http://stackoverflow.com/questions/1656227/how-does-valgrind-work schrieb:
Your program is then run on a synthetic CPU provided by the Valgrind core. As new code is executed for the first time, the core hands the code to the selected tool. The tool adds its own instrumentation code to this and hands the result back to the core, which coordinates the continued execution of this instrumented code.
Das klingt nicht so, als würde valgrind nur einige Hooks einfügen. Deswegen ist valgrind auch so langsam.
-
Gut, ich habe wieder was gelernt. Und liest man weiter, dann kann auch Nulgrind benutzt werden. Sicher gibt es zwischen "simulate every instruction" und "nothing" viele Optionen.
-
knivil schrieb:
Ich weiss um die Numerik dahinter Bescheid, nur kann ich den Zusammenhang mit Valgrind nicht herstellen. Valgrind installiert Hooks fuer free und malloc und fuehrt dein Programm aus und tracked deinen Speicher. Dabei kann ich keinen Einfluss auf numerische Berechnungen feststellen. Wo rundet Valgrind?
Naja, etwas mehr tut Valgrind sicher. Nach meinem Verständnis dürfte es
einen Prozessor simulieren und den Programmcode interpretieren. Anders
ist die Rundungsdifferenz nicht zu erklären, und die Performance ist ja
auch deutlich schlechter. Ah, na bitte, hier ist Info zum Thema:https://lists-sop.inria.fr/sympa/arc/cgal-discuss/2008-05/msg00151.html
http://valgrind.org/docs/manual/manual-core.html