all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* w32/w64 Emacs and gmalloc()
@ 2014-02-28 16:39 Fabrice Popineau
  2014-02-28 17:21 ` Stefan Monnier
  2014-03-01  6:58 ` Eli Zaretskii
  0 siblings, 2 replies; 13+ messages in thread
From: Fabrice Popineau @ 2014-02-28 16:39 UTC (permalink / raw
  To: emacs-devel


In case it is of interest for the future, I let you know that I have managed 
to build an Emacs for w32/w64 that runs without gmalloc.
The patch is far from clean enough to be presented, but the thing is running.

All the problem was about dumping the data. 
I did it in an array which is dumped with the executable.
This also removes the need of addsection.
It allows the resulting executable to be striped.

Once the preloaded data are dumped, they are not freed nor realloc'ed, or 
rather, the space they occupied is not collected. This is suboptimal, but 
there is no way around with the w32 api alone (no way that I know of without 
using your own allocator).
After the dumping, the normal emacs runs on the w32 heap management. 
Nowadays, the heap can be controlled in various ways, especially it can be 
turned into the so-called `low fragmentation heap'.
If anybody has a good benchmark that would be usable to tweak the parameters, 
I'll be glad to try it.

Any comments welcome on the pros/cons of this gmalloc removal for w32.

Best regards,

Fabrice




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-02-28 16:39 w32/w64 Emacs and gmalloc() Fabrice Popineau
@ 2014-02-28 17:21 ` Stefan Monnier
  2014-03-01  7:02   ` Eli Zaretskii
  2014-03-01  6:58 ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Stefan Monnier @ 2014-02-28 17:21 UTC (permalink / raw
  To: Fabrice Popineau; +Cc: emacs-devel

> Once the preloaded data are dumped, they are not freed nor realloc'ed, or 
> rather, the space they occupied is not collected.

What changes did you make to get this result?

> This is suboptimal, but there is no way around with the w32 api alone
> (no way that I know of without  using your own allocator).

IIUC the problem is with calling "malloc" before the dump and then
"free" that block after the dump, right?  If so, there's still some room
for improvement since Emacs could reuse a malloc'd area internally
(without going through free+malloc).

> Any comments welcome on the pros/cons of this gmalloc removal for w32.

Can you show your current patch (I promise I won't make any comment
about style etc...).


        Stefan



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-02-28 16:39 w32/w64 Emacs and gmalloc() Fabrice Popineau
  2014-02-28 17:21 ` Stefan Monnier
@ 2014-03-01  6:58 ` Eli Zaretskii
  2014-03-01  9:57   ` Fabrice Popineau
  1 sibling, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-01  6:58 UTC (permalink / raw
  To: Fabrice Popineau; +Cc: emacs-devel

> From: Fabrice Popineau <fabrice.popineau@gmail.com>
> Date: Fri, 28 Feb 2014 16:39:04 +0000 (UTC)
> 
> 
> In case it is of interest for the future, I let you know that I have managed 
> to build an Emacs for w32/w64 that runs without gmalloc.
> The patch is far from clean enough to be presented, but the thing is running.
> 
> All the problem was about dumping the data. 
> I did it in an array which is dumped with the executable.
> This also removes the need of addsection.
> It allows the resulting executable to be striped.

Thanks.

As discussed with you previously, please submit these changes once the
trunk is unfrozen, they are a most welcome addition to Emacs.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-02-28 17:21 ` Stefan Monnier
@ 2014-03-01  7:02   ` Eli Zaretskii
  2014-03-01 15:50     ` Stefan Monnier
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-01  7:02 UTC (permalink / raw
  To: Stefan Monnier; +Cc: fabrice.popineau, emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Fri, 28 Feb 2014 12:21:37 -0500
> Cc: emacs-devel@gnu.org
> 
> > Once the preloaded data are dumped, they are not freed nor realloc'ed, or 
> > rather, the space they occupied is not collected.
> 
> What changes did you make to get this result?

Fabrice implemented mmap emulation for Windows, for use in allocating
buffer text, and then uses system malloc for the rest of allocations.

> > This is suboptimal, but there is no way around with the w32 api alone
> > (no way that I know of without  using your own allocator).
> 
> IIUC the problem is with calling "malloc" before the dump and then
> "free" that block after the dump, right?

Yes, that's the problem.

> If so, there's still some room for improvement since Emacs could
> reuse a malloc'd area internally (without going through
> free+malloc).

If Emacs already does that, there's no problem.  What Fabrice wrote
just says that calls to 'free' that reference memory allocated before
dumping will be a no-op, and calls to 'realloc' that enlarge the block
will malloc new memory.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01  6:58 ` Eli Zaretskii
@ 2014-03-01  9:57   ` Fabrice Popineau
  0 siblings, 0 replies; 13+ messages in thread
From: Fabrice Popineau @ 2014-03-01  9:57 UTC (permalink / raw
  To: emacs-devel

Eli Zaretskii <eliz <at> gnu.org> writes:

> 
> As discussed with you previously, please submit these changes once the
> trunk is unfrozen, they are a most welcome addition to Emacs.
> 

Sure. I'm not in a hurry. There is certainly room for improvement over time.
First quick benchmark growing an empty list up to 10e8 elements shows
a performance enhancement of 10%. Results to be confirmed by more
extensive tests.

Fabrice
 







^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01  7:02   ` Eli Zaretskii
@ 2014-03-01 15:50     ` Stefan Monnier
  2014-03-01 16:00       ` Fabrice Popineau
  2014-03-01 18:05       ` Eli Zaretskii
  0 siblings, 2 replies; 13+ messages in thread
From: Stefan Monnier @ 2014-03-01 15:50 UTC (permalink / raw
  To: Eli Zaretskii; +Cc: fabrice.popineau, emacs-devel

> If Emacs already does that, there's no problem.  What Fabrice wrote
> just says that calls to 'free' that reference memory allocated before
> dumping will be a no-op, and calls to 'realloc' that enlarge the block
> will malloc new memory.

That sounds OK.  I'm just pointing out that it can be improved a bit by
exposing the "freeable_p" test and use it in sweep_foo so we don't even
try to free blocks when the free would be ignored.
Along the lines of the patch below.

Of course, maybe it's not worth the trouble.


        Stefan


=== modified file 'src/alloc.c'
--- src/alloc.c	2014-02-28 21:45:34 +0000
+++ src/alloc.c	2014-03-01 15:48:37 +0000
@@ -1173,7 +1173,8 @@
   ABLOCKS_BUSY (abase)
     = (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase));
 
-  if (2 > (intptr_t) ABLOCKS_BUSY (abase))
+  if (2 > (intptr_t) ABLOCKS_BUSY (abase)
+      && freeable_p ABLOCKS_BASE (abase))
     { /* All the blocks are free.  */
       int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase);
       struct ablock **tem = &free_ablock;
@@ -1884,7 +1885,8 @@
       /* Free blocks that contain free Lisp_Strings only, except
 	 the first two of them.  */
       if (nfree == STRING_BLOCK_SIZE
-	  && total_free_strings > STRING_BLOCK_SIZE)
+	  && total_free_strings > STRING_BLOCK_SIZE
+	  && freeable_p (b))
 	{
 	  lisp_free (b);
 	  string_free_list = free_list_before;




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 15:50     ` Stefan Monnier
@ 2014-03-01 16:00       ` Fabrice Popineau
  2014-03-01 18:08         ` Eli Zaretskii
  2014-03-01 18:05       ` Eli Zaretskii
  1 sibling, 1 reply; 13+ messages in thread
From: Fabrice Popineau @ 2014-03-01 16:00 UTC (permalink / raw
  To: Stefan Monnier; +Cc: Eli Zaretskii, Emacs developers

[-- Attachment #1: Type: text/plain, Size: 956 bytes --]

> That sounds OK.  I'm just pointing out that it can be improved a bit by
> exposing the "freeable_p" test and use it in sweep_foo so we don't even
> try to free blocks when the free would be ignored.
> Along the lines of the patch below.
>
> Of course, maybe it's not worth the trouble.
>
>
Good idea! I'll try it and keep it if it helps.

BTW, while working on this gmalloc removal, I noticed the following about
what kind of
memory allocations occur while undumping.
I had to look at the "big chunks" vs the "small chunks", big being over a
size of 0x80000
(don't ask why this constant, it is related to the w32 heap api).
Only a couple (actualy 5 or 6 at most) of them occur, except during the
loading of charset maps.
While loading charset maps, big vectors are allocated and freed right away
many times.

What I'm saying is that basically, all those big chunks could be made
static.
I'm not sure it is a good idea, but it is an obvious one.

Fabrice

[-- Attachment #2: Type: text/html, Size: 1501 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 15:50     ` Stefan Monnier
  2014-03-01 16:00       ` Fabrice Popineau
@ 2014-03-01 18:05       ` Eli Zaretskii
  2014-03-04  3:28         ` Stefan Monnier
  1 sibling, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-01 18:05 UTC (permalink / raw
  To: Stefan Monnier; +Cc: fabrice.popineau, emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: fabrice.popineau@gmail.com,  emacs-devel@gnu.org
> Date: Sat, 01 Mar 2014 10:50:18 -0500
> 
> I'm just pointing out that it can be improved a bit by exposing the
> "freeable_p" test and use it in sweep_foo so we don't even try to
> free blocks when the free would be ignored.  Along the lines of the
> patch below.

Will this handle all the calls to xrealloc we have in the sources?



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 16:00       ` Fabrice Popineau
@ 2014-03-01 18:08         ` Eli Zaretskii
  2014-03-01 20:12           ` Fabrice Popineau
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-01 18:08 UTC (permalink / raw
  To: Fabrice Popineau; +Cc: monnier, emacs-devel

> From: Fabrice Popineau <fabrice.popineau@gmail.com>
> Date: Sat, 1 Mar 2014 17:00:18 +0100
> Cc: Eli Zaretskii <eliz@gnu.org>, Emacs developers <emacs-devel@gnu.org>
> 
> Only a couple (actualy 5 or 6 at most) of them occur, except during the
> loading of charset maps.
> While loading charset maps, big vectors are allocated and freed right away
> many times.
> 
> What I'm saying is that basically, all those big chunks could be made
> static.

Are you talking about the big chunks used for charset maps, or about
the rest of them?  If the latter, what are they used for?  Which code
causes them to be allocated?



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 18:08         ` Eli Zaretskii
@ 2014-03-01 20:12           ` Fabrice Popineau
  2014-03-01 20:29             ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Fabrice Popineau @ 2014-03-01 20:12 UTC (permalink / raw
  To: Eli Zaretskii; +Cc: monnier, Emacs developers

[-- Attachment #1: Type: text/plain, Size: 2174 bytes --]

2014-03-01 19:08 GMT+01:00 Eli Zaretskii <eliz@gnu.org>:

> > From: Fabrice Popineau <fabrice.popineau@gmail.com>
> > Date: Sat, 1 Mar 2014 17:00:18 +0100
> > Cc: Eli Zaretskii <eliz@gnu.org>, Emacs developers <emacs-devel@gnu.org>
> >
> > Only a couple (actualy 5 or 6 at most) of them occur, except during the
> > loading of charset maps.
> > While loading charset maps, big vectors are allocated and freed right
> away
> > many times.
> >
> > What I'm saying is that basically, all those big chunks could be made
> > static.
>
> Are you talking about the big chunks used for charset maps, or about
> the rest of them?  If the latter, what are they used for?  Which code
> causes them to be allocated?
>

The rest of them.
When doing 'temacs -batch -l loadup dump'
there are 4 occurences before loading the charset maps.
They all belong to make-hash-table

(gdb) run -batch -l loadup dump
Starting program: C:\source\gnu\emacs\mingw\src/temacs.exe -batch -l loadup
dump
[New Thread 59040.0xb09c]
Loading loadup.el (source)...
[New Thread 59040.0x113c]

#0  e_malloc (size=1120016) at w32heap-new.c:359
#1  0x00000004000f1b21 in lisp_malloc (nbytes=nbytes@entry=1120016,
    type=type@entry=MEM_TYPE_VECTORLIKE) at alloc.c:893
Lisp Backtrace:
"make-hash-table" (0x83edf0)
"setq" (0x83ef68)
"if" (0x83f058)
"load" (0x83f750)
(gdb) c

They all have the same elisp backtrace, the next sizes are:
nbytes=nbytes@entry=560016,
nbytes=nbytes@entry=560016,
nbytes=nbytes@entry=700040,

Then we have a bunch of :
Lisp Backtrace:
"define-charset-internal" (0x83e398)
"apply" (0x83e540)
"define-charset" (0x83e770)
"byte-code" (0x83e970)
"load" (0x83f060)
"load" (0x83f750)

and then of :
Lisp Backtrace:
"map-charset-chars" (0x83e7d0)
"byte-code" (0x83e970)
"load" (0x83f060)
"load" (0x83f750)

and last 3 occurences of :
size=size@entry=786440
Lisp Backtrace:
"decode-char" (0x83e798)
"byte-code" (0x83e970)
"load" (0x83f060)
"load" (0x83f750)

And after looking more carefully, all those chunks are released before
dumping!
So I could really handle them differently and shrink the data area which is
dumped.
Well, unfortunately, maybe it is not a future proof assumption.

Fabrice

[-- Attachment #2: Type: text/html, Size: 3933 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 20:12           ` Fabrice Popineau
@ 2014-03-01 20:29             ` Eli Zaretskii
  0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-01 20:29 UTC (permalink / raw
  To: Fabrice Popineau; +Cc: monnier, emacs-devel

> From: Fabrice Popineau <fabrice.popineau@gmail.com>
> Date: Sat, 1 Mar 2014 21:12:01 +0100
> Cc: monnier <monnier@iro.umontreal.ca>, Emacs developers <emacs-devel@gnu.org>
> 
> And after looking more carefully, all those chunks are released before
> dumping!
> So I could really handle them differently and shrink the data area which is
> dumped.

Indeed, and so I guess this problem is not really about a few large
chunks, but rather about many small ones.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-01 18:05       ` Eli Zaretskii
@ 2014-03-04  3:28         ` Stefan Monnier
  2014-03-04  3:49           ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Monnier @ 2014-03-04  3:28 UTC (permalink / raw
  To: Eli Zaretskii; +Cc: fabrice.popineau, emacs-devel

>> I'm just pointing out that it can be improved a bit by exposing the
>> "freeable_p" test and use it in sweep_foo so we don't even try to
>> free blocks when the free would be ignored.  Along the lines of the
>> patch below.
> Will this handle all the calls to xrealloc we have in the sources?

Not sure what you mean.  I think the answer is "no" because we're not
trying to optimize all cases, only those that we (easily) can.


        Stefan



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: w32/w64 Emacs and gmalloc()
  2014-03-04  3:28         ` Stefan Monnier
@ 2014-03-04  3:49           ` Eli Zaretskii
  0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2014-03-04  3:49 UTC (permalink / raw
  To: Stefan Monnier; +Cc: fabrice.popineau, emacs-devel

> From: Stefan Monnier <monnier@IRO.UMontreal.CA>
> Cc: fabrice.popineau@gmail.com, emacs-devel@gnu.org
> Date: Mon, 03 Mar 2014 22:28:03 -0500
> 
> >> I'm just pointing out that it can be improved a bit by exposing the
> >> "freeable_p" test and use it in sweep_foo so we don't even try to
> >> free blocks when the free would be ignored.  Along the lines of the
> >> patch below.
> > Will this handle all the calls to xrealloc we have in the sources?
> 
> Not sure what you mean.  I think the answer is "no" because we're not
> trying to optimize all cases, only those that we (easily) can.

What I meant is this: if some cases of xrealloc still remain that will
try to reallocate a buffer allocated before dumping, then we still
need code to intercept the reallocation and make it call malloc
without freeing the frozen memory.



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-03-04  3:49 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-28 16:39 w32/w64 Emacs and gmalloc() Fabrice Popineau
2014-02-28 17:21 ` Stefan Monnier
2014-03-01  7:02   ` Eli Zaretskii
2014-03-01 15:50     ` Stefan Monnier
2014-03-01 16:00       ` Fabrice Popineau
2014-03-01 18:08         ` Eli Zaretskii
2014-03-01 20:12           ` Fabrice Popineau
2014-03-01 20:29             ` Eli Zaretskii
2014-03-01 18:05       ` Eli Zaretskii
2014-03-04  3:28         ` Stefan Monnier
2014-03-04  3:49           ` Eli Zaretskii
2014-03-01  6:58 ` Eli Zaretskii
2014-03-01  9:57   ` Fabrice Popineau

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.