Gibt es im gforth einen weg heraus zu finden wieviel ram des rechners
ich per allocate maximal ergattern kann? Wird bei wiederholtem
allocate ein weiterer speicherbereich zur verfügung gestellt?
Den verbleibenden platz fürs dictionary finde ich ja mit unused.
Im unused steht auch:
see usable-dictionary-end
: usable-dictionary-end
dictionary-end 234 - ; ok
Hm, warum 234 abziehen? Die stacks liegen doch woanders.
Gibt es eine Beschreibung der Speicheraufteilung bzw Zuweisungen in
der das näher beschreiben steht?
Fragen über fragen - das kommt davon wenn man "herumeulert". Manche
Aufgaben dort veranlassen mich den Speicherplatz auszuloten. ;-)
Michael
Nein. Je nach Betriebssystem und seiner Konfiguration kann man sogar
mehr ALLOCATEn als RAM und Swap-Space zur Verfuegung steht. Nur
Benutzen sollte man das dann nicht alles.
> Wird bei wiederholtem
>allocate ein weiterer speicherbereich zur verf=FCgung gestellt?
Jedes ALLOCATE stellt einen Speicherbereich zur Verfuegung, der sich
mit den anderen noch nicht freigegebenen nicht ueberlappt.
>Den verbleibenden platz f=FCrs dictionary finde ich ja mit unused.
>Im unused steht auch:
>see usable-dictionary-end
>: usable-dictionary-end
> dictionary-end 234 - ; ok
>
>Hm, warum 234 abziehen?
Es muss noch Platz fuer den WORD-buffer und ein bisschen was im PAD
uebrigbleiben. Und der HOLD-Buffer wird dabei wold auch
beruecksichtigt (obwohl der inzwischen woanders liegt).
>Gibt es eine Beschreibung der Speicheraufteilung bzw Zuweisungen in
>der das n=E4her beschreiben steht?
Den Quellcode. Da steht's auch deutlicher drinnen. Z.B.:
: usable-dictionary-end ( -- addr )
dictionary-end [ word-pno-size pad-minsize + ] Literal - ;
- anton
--
M. Anton Ertl Some things have to be seen to be believed
an...@mips.complang.tuwien.ac.at Most things have to be believed to be seen
http://www.complang.tuwien.ac.at/anton/home.html
Allmählich begreife ich was Bernd neulich meinte:
http://www.forth-ev.de/wiki/doku.php/en:various:forth_is_readable
:)
Michael
Hm. Kriege auf dem Mac PowerBook G4 maimal 65533 Bytes; jedenfalls
behauptet das mein Test, oder?
Kann man das auf diese Weise überhaupt verlässlich testen?
Screenshot:
$ffff allocated-bytes
*the terminal*:1: Invalid memory address
$ffff allocated-bytes
^^^^^^^^^^^^^^^
Backtrace:
$1026610 @
adr adr0 - . 65533 ok
$fff allocated-bytes 4096 ok
<code>
0 value adr0
0 value adr
: allocated-bytes ( n -- )
{ n }
n allocate throw dup to adr0 to adr
0 begin
adr @ dup adr c! adr @ <>
if ." invalid mem at" adr .
adr0 free throw exit then
adr 1+ to adr
1+ dup n > until drop
adr adr0 - .
adr0 free throw ;
</code>
Grüße, Michael
Komisch, dass das auf dem PowerPC überhaupt funktioniert, du greifst da ja
auf ungerade Adressen mit @ zu (auf Linux/x86_64 klappt das auch für
erheblich größere Speicherbereiche, wenn auch sehr langsam). Füll doch
einfach den Speicher mit FILL, das geht schneller - wenn FILL fehlschlägt
(wegen overcommit), dann war's wohl nichts.
--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://www.jwdt.com/~paysan/
Dein Test ist falsch. Du versuchst, ueber das Ende des allozierten
Speichers hinaus zu schreiben, und wenn Du's das erste mal versucht,
gibt's eine SIGSEGV vom Betriebssystem (Gforth macht daraus dann ein
THROW, das das System faengt und die Meldung "Invalid memory address"
ausgibt.
>Kann man das auf diese Weise =FCberhaupt verl=E4sslich testen?
Nein.
PowerPC ist da ganz wie IA-32 und AMD64: der Zugriff ist langsamer,
aber er funktioniert; nur wenn Du PowerPC als little-endian zu
betreiben versuchtest, wuerde er auf Alignment Wert legen.
>Füll doch
>einfach den Speicher mit FILL, das geht schneller - wenn FILL fehlschlägt
>(wegen overcommit), dann war's wohl nichts.
Wenn Du overcommitteten Speicher voll auszunutzen versuchst, dann
schlaegt das Programm nicht offensichtlich fehl, sondern es kommt der
schwarze Mann (auch als out-of-memory Killer bekannt) und bringt einen
Prozess nach dem anderen um, bis er den richtigen erwischt. Sowas zu
versuchen, ist also nicht zu empfehlen, es kann das ganze System
unbrauchbar machen, wenn's den falschen Prozess erwischt.
On 9 Mai, 22:38, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:
> Michael Kalus <michael.ka...@onlinehome.de> writes:
> >On 9 Mai, 00:42, an...@mips.complang.tuwien.ac.at (Anton Ertl) wrote:
> >> Michael Kalus <michael.ka...@onlinehome.de> writes:
> >> >Gibt es im gforth einen weg heraus zu finden wieviel ram des rechners
> >> >ich per allocate maximal ergattern kann?
>
> >> Nein. Je nach Betriebssystem und seiner Konfiguration kann man sogar
> >> mehr ALLOCATEn als RAM und Swap-Space zur Verfuegung steht. Nur
> >> Benutzen sollte man das dann nicht alles.
>
> >Hm. Kriege auf dem Mac PowerBook G4 maimal 65533 Bytes; jedenfalls
> >behauptet das mein Test, oder?
>
> Dein Test ist falsch. Du versuchst, ueber das Ende des allozierten
> Speichers hinaus zu schreiben, und wenn Du's das erste mal versucht,
> gibt's eine SIGSEGV vom Betriebssystem (Gforth macht daraus dann ein
> THROW, das das System faengt und die Meldung "Invalid memory address"
> ausgibt.
>
Hm, in ADR sollte im Fall des SIGSEGV dann aber stehen bis wo es gut
gegangen ist.
Und ADR0 ADR - . müsste die tatsächlich benutzbare Speichergröße sein.
Und das sind beim Mac dann nie mehr als 65533 Bytes pro allocate.
Allociere ich weniger als diese 65533 Bytes läuft der code ja durch
und druckt die Anzahl.
64K ist also das Maximum an RAM das man per ALLOCATE kriegen kann?
Michael
Das tut es; allerdings greifst Du bei ADR0 65533 + @ auch auf die
Adresse ADR0 65536 + zu, und das ist schon jenseits des
Speicherbereichs, den Du allokiert hast.
>Und ADR0 ADR - . m=FCsste die tats=E4chlich benutzbare Speichergr=F6=DFe sei=
>n.
Selbst wenn Dein Programm es richtig machen wuerde, z.B. indem Du mit
C@ statt @ arbeitest, wuerde das nicht so funktionieren. Entweder:
Ohne overcommit: liefert das ALLOCATE einen Fehler, wenn es nicht mehr
Speicher committen kann, oder:
Mit overcommit: ALLOCATE liefert keinen Fehler, aber wenn irgendwann
beim C! geht dem Betriebssystem dann der Speicher aus, und es faengt
an, Prozesse umzubringen, um Speicher freizukriegen; mit ein bisschen
Glueck bringt es Gforth um, bevor es wichtigere Prozesse umbringt.
Auch in diesem Fall siehst Du nicht, wann das passiert, sondern nur,
dass Gforth irgendwann stirbt (wenn nichts wichtigeres).
>Und das sind beim Mac dann nie mehr als 65533 Bytes pro allocate.
>Allociere ich weniger als diese 65533 Bytes l=E4uft der code ja durch
>und druckt die Anzahl.
>
>64K ist also das Maximum an RAM das man per ALLOCATE kriegen kann?
Nein. Nur sind 64K offenbar in Deinem Fall eine Menge, wo zufaellig
unmittelbar hinter dem ALLOCATEden Bereich ein hardwaremaessig (per
MMU) geschuetzter nicht zugreifbarer Adressbereich war, bei dem der
Fehler in Deinem Programm sich dann bemerkbar machte.
Wie gibt man denn dann dem gforth unter linux einen sicher verfügbaren
maximalen Bereich an RAM?
UNUSED gibt mir das was für das gforth noch an dictionary übrig ist.
gforth bekommt als prozess 640KB.
Aber wie spreche ich den dicken Batzen RAM der da so im Rechner
herumliegt an? Da sind bei mir hier noch so typisch 300MB frei.
Michael
Als Systemadministrator kannst Du folgendes versuchen:
echo 2 >/proc/sys/vm/overcommit_memory
# und eventuell noch /proc/sys/vm/overcommit_ratio aendern
Dann kriegst Du eher einen Fehler bei ALLOCATE und kannst
wahrscheinlich das System nicht dazu bringen, Prozesse umzubringen.
Die Frage ist allerdings: Wozu willst Du wissen, was der maximale
Speicher ist? Versuch einfach, soviel zu allokieren, wie Du brauchst,
und lass den Rest Sorge des Systemadministrators sein. Es ist auch
ziehmlich asozial, sich alles zu nehmen, und den anderen Prozessen
nichts uebrig zu lassen.
>UNUSED gibt mir das was f=FCr das gforth noch an dictionary =FCbrig ist.
>gforth bekommt als prozess 640KB.
>
>Aber wie spreche ich den dicken Batzen RAM der da so im Rechner
>herumliegt an? Da sind bei mir hier noch so typisch 300MB frei.
300 1024 * 1024 * allocate throw
Oder, wenn Du's im Dictionary haben willst:
gforth -m 300M
> Die Frage ist allerdings: Wozu willst Du wissen, was der maximale
> Speicher ist? Versuch einfach, soviel zu allokieren, wie Du brauchst,
> und lass den Rest Sorge des Systemadministrators sein. Es ist auch
> ziehmlich asozial, sich alles zu nehmen, und den anderen Prozessen
> nichts uebrig zu lassen.
Nun, der admin auf meinem Laptop bin ich ja selbst. Beim
herumprobieren im project euler kommt man schon mal auf die Idee, bei
der einen oder anderen Aufgabe könnte viiiiiiel Speicher helfen. Ob
das dann wirklich auch nötig ist sei mal dahin gestellt. Jedenfalls
kam bei der Suche nach RAM fürs gforth ans ALLOCATE und UNUSED und
schon hatte plötzlich wieder Fragen über Fragen. :-) Aber die hast du
hier sehr gut beantwortet inzwischen, wofür ich dir sehr danken möchte
an dieser Stelle. Das war wirklich hilfreich.
...
> Oder, wenn Du's im Dictionary haben willst:
>
> gforth -m 300M
Aha, ja, das tuts.
: test unused 0 do $55 c, loop ; test
Und man kann in der Aktivitäts-Anzeige des OSX tatsächlich zusehen,
wie jede Sekunde der Prozess gforth um 1MB größer wird. Das dauert,
habs dann auch vorsichtshalber erst mal beim Stand von 100MB
abgebrochen.
Aber das ist gut zu wissen, und dürfte meinen Euler getriebenen
Speicherplatzhunger für eine Weile stillen. ;-)
> M. Anton Ertl Some things have to be seen to be believed
So isses. Danke für die Einsichten.
Michael
Na, man fragt nach, ob /proc/sys/vm/overcommit_memory 0 ist. Wenn das so
ist, dann schlägt ALLOCATE fehl, wenn es nicht ausreichend RAM gibt. Wenn
das 1 ist, dann kann man noch /proc/meminfo auslesen, und memfree+swapfree
zusammenzählen. Die sind dann aber auch nicht sicher, es könnte ja
hinterher noch ein anderer Prozess kommen, der ebenfalls Speicher belegt,
und irgendwann kann's halt bei überbuchtem Speicher krachen.
> UNUSED gibt mir das was für das gforth noch an dictionary übrig ist.
> gforth bekommt als prozess 640KB.
>
> Aber wie spreche ich den dicken Batzen RAM der da so im Rechner
> herumliegt an? Da sind bei mir hier noch so typisch 300MB frei.
Mit ALLOCATE. Du kriegst nur keine Information, wieviel das ist. Nimm dir,
soviel du brauchst, nicht soviel wie da ist.
Leider nein. 0 ist der Modus, der die Nachteile von Overcommit (der
Out-of-memory-killer kann zuschlagen) mit den Nachteilen von
no-overcommit (mmap()/ALLOCATE schlaegt aufgrund aeusserer Umstaende
fehl) vereinigt; natuerlich ist das der Default in Linux:-(. 1 gibt
einem overcommit, und 2 einen Versuch, sich so aehnlich zu verhalten
wie no-overcommit (laut doku sogar dann, wenn man mit MAP_NORESERVE
sagt, dass man overcommit haben will).
Hier ein schoenes Beispiel, wie idiotisch der 0-Modus ist:
sh cat /proc/sys/vm/overcommit_memory
0
ok
sh free
total used free shared buffers cached
Mem: 511664 408036 103628 0 18696 207492
-/+ buffers/cache: 181848 329816
Swap: 2104472 0 2104472
ok
2000000000 allocate throw .s <1> 46912512880656 ok
2000000000 allocate throw .s <2> 46912512880656 46914512883728 ok
2000000000 allocate throw .s <3> 46912512880656 46914512883728 46916512886800 ok
2000000000 allocate throw .s <4> 46912512880656 46914512883728 46916512886800 46918512889872 ok
free throw free throw free throw free throw .s <0> ok
3000000000 allocate throw .s
:9: Cannot allocate memory
3000000000 allocate >>>throw<<< .s
Backtrace:
Also mit ca. 2.5GB freiem virtuellen Speicher gibt mir das System ohne
weiters 8GB in einem Prozess in 2GB-Stuecken, aber nicht 3GB in einem
Stueck. Mit MAP_NORESERVE kann man das Richtung overcommit
korrigieren:
[~/gforth:60964] gforth -m 3G
Gforth 0.6.9-20080430, Copyright (C) 1995-2006,2007 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
unused . 3220875354 ok