[Gelößt]Verringern des Arbeitsspeicherverbrauchs

Alles rund um die Programmierung mit Qt
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

[Gelößt]Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

Hallo,

mein System:
Qt: 3.3.7 Embedded
System: Linux 2.6.9
Architektur: arm
ROM: 16 MB
RAM: 32 MB
CPU: ARM9 192 MHZ

Ich habe eine Applikation geschrieben welche im Embedded Bereich zum Einsatz kommt. Da mein Zielsystem Hardware technisch sehr schwach ausgerüstet ist muss meine Applikation mit den Ressourcen schonend umgehen. Mir stehen lediglich 32 MB Arbeitsspeicher zur Verfügung von denen ich effektiv maximal 15 MB nutzen kann. Meine Applikationen nutzt keine Gui-Elemente.

Folgende Anpassung zwecks Performance wurden bereits getätigt:
* statisches Linken der Qt Bibliothek
* Nicht benötigte QT-Module beim kompilieren der QT Bibliothek verwerfen

Code: Alles auswählen

Configure Parameter:
./configure -qconfig moxa -thread -embedded arm -nomake demos -nomake examples -no-zlib -little-endian -static -no-cups -no-libjpeg -no-freetype -no-libmng  -no-libpng -nomake tools -no-imgfmt-mng -no-imgfmt-jpeg

QConfig-Einstellungen:


//#ifndef QT_NO_CHECK
//# define QT_NO_CHECK
//#endif
#define QT_NO_PROCESS
#define QT_NO_PALETTE
#define QT_NO_ACTION

#define QT_NO_TRANSLATION
#define QT_NO_MIME
#define QT_NO_SOUND

#define QT_NO_QWS_CURSOR
#define QT_NO_QWS_DEPTH_8GRAYSCALE
#define QT_NO_QWS_DEPTH_8
#define QT_NO_QWS_DEPTH_15
#define QT_NO_QWS_DEPTH_16
#define QT_NO_QWS_DEPTH_32

#define QT_NO_IMAGEIO_BMP
#define QT_NO_IMAGEIO_PPM
#define QT_NO_IMAGEIO_XBM
#define QT_NO_IMAGEIO_XPM
#define QT_NO_ASYNC_IMAGE_IO
#define QT_NO_MOVIE
#define QT_NO_TRUETYPE
#define QT_NO_BDF
//#define QT_NO_FONTDATABASE
#define QT_NO_RICHTEXT
#define QT_NO_DRAGANDDROP
#define QT_NO_CLIPBOARD

#define QT_NO_QWS_CURSOR
#define QT_NO_CURSOR
#define QT_NO_QWS_GFX_SPEED
#define QT_NO_COLORNAMES
#define QT_NO_TRANSFORMATIONS
#define QT_NO_PRINTER
#define QT_NO_PSPRINTER
#define QT_NO_PICTUpsRE
#define QT_NO_PICTURE
#define QT_NO_LAYOUT
#define QT_NO_DRAWUTIL
#define QT_NO_IMAGE_TRUECOLOR
#define QT_NO_IMAGE_SMOOTHSCALE
#define QT_NO_IMAGE_TEXT
#define QT_NO_QWS_MANAGER
#define QT_NO_TEMPLATE_VARIANT
#define QT_NO_QWS_KEYBOARD
#define QT_NO_SYNTAXHIGHLIGHTER

#define QT_NO_ACCEL
#define QT_NO_BUTTON
#define QT_NO_DIALOG
#define QT_NO_FRAME
#define QT_NO_SEMIMODAL

#define QT_NO_STYLE
#define QT_NO_EFFECTS
#define QT_NO_COP

#define QT_NO_SQL

#define QT_NO_IMAGEIO

#define QT_NO_NETWORKPROTOCOL
#define QT_NO_NETWORKPROTOCOL_FTP
#define QT_NO_NETWORKPROTOCOL_HTTP

#define QT_NO_IMAGE_DITHER_TO_1
#define QT_NO_IMAGE_HEURISTIC_MASK
#define QT_NO_IMAGE_MIRROR
#define QT_NO_DIRECTPAINTER

#define QT_NO_DIALOGS
#define QT_NO_WIDGETS


#define QT_NO_SPLITTER
#define QT_NO_STATUSBAR
#define QT_NO_TABBAR
#define QT_NO_TOOLBAR
#define QT_NO_TOOLTIP
#define QT_NO_VALIDATOR
#define QT_NO_WHATSTHIS
#define QT_NO_WIDGETSTACK
#define QT_NO_SIZEGRIP
#define QT_NO_HEADER
#define QT_NO_WORKSPACE
#define QT_NO_LCDNUMBER
#define QT_NO_STYLE_MOTIF
#define QT_NO_STYLE_PLATINUM
#define QT_NO_PROGRESSBAR
#define QT_NO_MENUDATA

Meine Applikation hat drei Threads. Der erste wertet Rs232 Signale aus, der zweite Kommuniziert über eine socket Verbindung und der dritte sorgt für einen FTP-Upload zusätzlich natürlich noch der Main-Thread... Mein Arbeitsspeicherverbrauch liegt derzeit bei ca. 14 MB wobei ich nicht nachvollziehen kann was da so groß sein soll. Mit "pmap" ein Linux-Tool kann man sich Informationen über den Prozess Arbeitsspeicher anzeigen lassen. Hierbei verbrauchen die Bibliotheken unter 4 MB jedoch der Eintrag [anon] über 9 MB.. [anon] sagt natürlich nicht viel aus vermute mal das wird der Stack etc.. sein


Hat jemand eine Idee wie ich meinen Arbeitsspeicherverbrauch weiter senken kann und ob der derzeite verbrauch normal ist?

[EDIT]: ich habe mir mal genauer den Prozess meiner Applikation angesehen. Unter Linux /proc/PID kann man sich zu dem jeweiligen Prozess alle möglichen Daten ausgeben lassen. Mir ist dabei aufgefallen das auf dem Embedded Gerät vier Prozesse laufen und auf dem Entwicklungsrechner nur ein Prozess läuft meiner Software. Die Gesamtgröße des Programmes in Seiten pro Prozess beträgt auf dem embedded Gerät ca. 3 MB *4 Prozesse = 12 MB Arbeitsspeicher verbrauch. Kann mir jemand erklären wie es zu diesem Ergebnis kommt? Wird wirklich für jeden Thread das komplette Programm im Speicher gehalten?

Gruß Alex
Zuletzt geändert von Alex66955 am 23. September 2011 10:55, insgesamt 1-mal geändert.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von RHBaum »

Meine Applikationen nutzt keine Gui-Elemente
QT Bibliothek
muss meine Applikation mit den Ressourcen schonend umgehen
Das sind irgendwie Punkte die sich beissen :-)

Wozu brauchst du bitte die Qt, wenn du keine GUI hasst ?

Warum so eine alte Version. Fuer embedded sollte doch auch ne 4er version verfuegbar sein ?
Die trennt wenigstens die unteschiedlichen module, so das das grafik zeugs ned mit anziehen muesstest ...

Optimierung hinsichtlich Speicherverbrauch wird dir im Code mit der Qt schwerfallen ... dank implizieten sharing und dem GC like Handling der Qt Objecte.
Aber geben wirds sicherlich trotzdem noch genug punkte ... :-)

Ciao ...
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

Wozu brauchst du bitte die Qt, wenn du keine GUI hasst ?
Hintergrund war alle Module die nicht benötigt werden zu deaktivieren also auch die GUI. Qt bietet ja noch mehr als nur GUI-Elemente.. Plattformunabhängigkeit, Zahlreiche Hilfreiche Module wie XML-parsing, Network etc..
Warum so eine alte Version. Fuer embedded sollte doch auch ne 4er version verfuegbar sein ?
Mein embedded gerät hat eine veraltete glibc und andere Abhängigkeiten die Qt4 voraussetzt. In kurzer zeit war es mir nicht möglich mit der mitgelieferten tool-chain alle Abhängigkeiten zu übersetzen bzw. ein Test Programm mit QT4 zum laufen zu bringen.

Gruß
Alex
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von solarix »

Alex66955 hat geschrieben:Hierbei verbrauchen die Bibliotheken unter 4 MB jedoch der Eintrag [anon] über 9 MB.. [anon] sagt natürlich nicht viel aus vermute mal das wird der Stack etc.. sein
Der Stack wird bei mir separat angezeigt ("[stack]"). "anon" steht IMHO für "anonym" und damit für grosse HEAP-Blöcke. Ich habe das mal schnell getest: allokiere ich in einer test-main.cc ein Block (z.B. 32M) erhalte ich sauber ein entsprechender "anon"-Eintrag in pmap.

Daher: irgendwas in deiner Software braucht halt einfach 9Mb.. was das ist, kannst eigentlich nur du herausfinden... Falls du selbst nicht weisst, was es ist, musst du halt bei einer leeren Eventloop anfangen und Modul um Modul dazuschalten (z.B. Thread um Thread erstellen und starten) und achten, wann denn genau der 9M-Anstieg kommt..

hth!



[EDIT]
http://oreilly.com/catalog/spt2/chapter/ch04.html hat geschrieben: Heap space
Consists of memory allocated by means of malloc(3). This is called anonymous memory, because it has no mapping in the filesystem (we'll discuss it further in "Anonymous memory" later in this chapter).
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von RHBaum »

Entwickeln und Debuggen tust du doch aufm PC dann oder ?
also gdb und valgrind solltest du zum laufen bringen ....
Qt bietet ja noch mehr als nur GUI-Elemente.. Plattformunabhängigkeit, Zahlreiche Hilfreiche Module wie XML-parsing, Network etc..
Ja und es bietet diese Funktionalitaet etwas userfreundlicher an als wie andere :-) Nur das hat auch seinen Preis.

Und die Grundlagen hat QT auch von anderen Projekten uebernommen, bzw parallel dazu entwickelt, so das es immer Alternativen gibt.

XML -> Xerces-c / tinyXML ...
Signale / Slots -> boost::signals
Threads -> Posix Threads(sollte es auch ne Kompatiblitaetslib fuer windows geben) / boost::thread
Network -> Naja, sowas wie QT da macht, wirst nirgends bekommen ^^ aber das ist auch nen Moloch. Sprich speicherschonend isses sicher nicht. HTML, ftp usw Implementationen und Support libs findest aber auch.

Wozu brauchst du eigentlich Plattformunabhaengigkeit ?

Aber denk das nicht dein Hauptproblem.

Schau erst mal wo er die 9Mb verbraet, dann überleg, was da anders machen kannst ...

Ciao ...
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

Soo..

Ich habe mal alle Threads auskommentiert und anschließend mit Pmap den Prozess analysiert. Siehe da die "anon" Einträge sind unter 130 KBytes. Erstelle ich jetzt einen neuen Thread mit nur einer Run-Methode habe ich einen "anon" Eintrag von 8000 KBytes also knappe 7 MB.
Wenn ich meine Applikation betrachte mit 3 threads a 7MB, kein wunder das dann meine Anwenung nach einer weile abstürzt wegen Speicherknappheit.

Also definitiv ist QThread schuld.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von franzf »

Also definitiv ist QThread schuld.
Das wage ich zu bezweifeln! Nimm mal ein nackiges QThread-Objekt und starte es. Dann wirst du recht wahrscheinlich keine zusätzlichen 8000kb "anon" haben. Du wirst halt in deinem Thread recht viel Speicher alloziieren, vllt. auch nur indirekt.
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

as wage ich zu bezweifeln! Nimm mal ein nackiges QThread-Objekt und starte es. Dann wirst du recht wahrscheinlich keine zusätzlichen 8000kb "anon" haben. Du wirst halt in deinem Thread recht viel Speicher alloziieren, vllt. auch nur indirekt.
Meine Test QT Klasse sieht wie folgt aus:

.h

Code: Alles auswählen

#ifndef TEST_H_
#define TEST_H_

#include <qthread.h>

class test: public QThread {
public:
	test();
	void run();
};

#endif /* TEST_H_ */
.cpp

Code: Alles auswählen

#include "test.h"

test::test(){
}

void test::run(){

}
[EDIT]:
Ohne Threads wie gesagt um die 300 KB mit dieser test Klasse 8000 KB
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von solarix »

Kann ich bestätigen..

aber jetzt kommt dein (zum Glück nicht meins) Problem:

Code: Alles auswählen

#include <QCoreApplication>
#include <QDebug>
#include <pthread.h>

void* threadMain(void*)
{
  qDebug() << "RUN2";
  return NULL;
}

int main(int argc, char *argv[])
{
  QCoreApplication app(argc,argv);

  pthread_t tid;
  pthread_create(&tid,NULL,threadMain,NULL);

   return app.exec();
}
Da hat man das gleiche Ergebnis.. mit anderen Worten: nicht QThread erzeugt dieser Block, sondern pthread_create..

Die Frage lautet daher: wie machen das (Threading) die Embedded-Leute? Verwenden die einen anderen (optimierten) Kernel oder eine andere Thread-Library?

hth..
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

Mhh

Mit ulimit -s -->8192 komme ich genau auf den Wert pro Thread.

Bin noch am Suchen was er bedeutet

[EDIT]:
-t: cpu time (seconds)
-f: file size (blocks)
-d: data seg size (kbytes)
-s: stack size (kbytes)
-c: core file size (blocks)
-m: resident set size (kbytes)
-u: processes
-n: file descriptors
-l: locked-in-memory size (kb)
-v: address space (kb)
-x: file locks unlimited

Ich Teste mal mit geändertem Limit

TEST:
Mit geändertem Limit momentan 1024 KB wird pro Thread lediglich 1036 KB verwendet. Momentan läuft noch alles die frage ist nur ob das ganze zu Probleme führen kann..Vermutlich ein Stack Overflow
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von solarix »

Interessant.. aber ich frage mich inwiefern dich das überhaupt betrifft.. dieser Speicher wurde zwar bei der libc angefordert, jedoch noch gar nicht genutzt.. jedenfalls steigt in "top" der effektive Speicherverbrauch des Prozesses bei mir pro Thread nur um etwa 100bytes an.
Oder mit anderen Worten: nur weil bei deinem Prozess bei pmap "8M [anon]" steht, heisst das nicht, dass ein anderer Prozess ein "out-of-memory" kriegt....
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

Interessant.. aber ich frage mich inwiefern dich das überhaupt betrifft.. dieser Speicher wurde zwar bei der libc angefordert, jedoch noch gar nicht genutzt.. jedenfalls steigt in "top" der effektive Speicherverbrauch des Prozesses bei mir pro Thread nur um etwa 100bytes an.
Oder mit anderen Worten: nur weil bei deinem Prozess bei pmap "8M [anon]" steht, heisst das nicht, dass ein anderer Prozess ein "out-of-memory" kriegt....
Mhh..
Also der Eintrag von "pmap" sagt mir momentan bei writeable/private: 4548K mit den drei Threads. Stelle ich das Limit wieder hoch steigt auch der writeable/private Eintrag entsprechend (writeable/private: 33088K). Top bestätigt die ausgelesenen Werte
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von solarix »

Code: Alles auswählen

$ pmap  <id> | grep -i private
$ pmap  <id> | grep -i write
$ pmap  -x <id> | grep -i private
$ pmap  -x <id> | grep -i write
$ 
was genau meinst du mit "writeable/private"?
Alex66955
Beiträge: 56
Registriert: 23. September 2009 14:48

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von Alex66955 »

was genau meinst du mit "writeable/private"?
Bei "pmap -d PID" gibt es bei mir nur einen Eintrag

Auf dem Entwicklungsrechner klappt das alles sehr gut. Nur auf dem embedded Gerät gibt es diesen Effekt nicht beim herunter setzen des Limits. Gibt es noch andere stellen an denen das Limit gesetzt werden muss, kann?
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Re: Verringern des Arbeitsspeicherverbrauchs

Beitrag von pfid »

Wir haben das mal so gelöst:

Code: Alles auswählen

      if (stackSize == na)
      {
         res = pthread_create(&childTid, 0, (void*(*)(void*))&startThread, (void *)this);
      }
      else
      {
         pthread_attr_setstacksize(&attr, stackSize);

         res = pthread_create(&childTid, &attr, (void*(*)(void*))&startThread, (void *)this);
      }
Ob QT dafür ne API anbietet, weiß ich jetzt nicht.

http://linux.die.net/man/3/pthread_attr_setstacksize
Antworten