On my 64-bit Mac, I get
(time (##make-vector 8))
(time (##make-vector 8)) 0 ms real time 0 ms cpu time (0 user, 0 system) no collections 144 bytes allocated 1 minor fault no major faults #(0 0 0 0 0 0 0 0)
I'd figure this allocates only 8 (header) + 8 (words) * 8 (bytes/word) = 72 bytes, but time is reporting 144.
Similarly (and what led me to this),
(time (##bignum.make 2 #f #f))
(time (##bignum.make 2 #f #f)) 0 ms real time 0 ms cpu time (0 user, 0 system) no collections 48 bytes allocated no minor faults no major faults
(don't do this at home!), which I expect allocates 8 (header) + 2 (adigits) * 8 (bytes/adigit) = 24 bytes.
What am I not understanding?
More generally, can the number of bytes reported be confused by stack manipulation? I.e., if things go on the stack, but then the stack is unwound, does "time" report any allocation?
Thanks.
Brad
Afficher les réponses par date
The "space allocated" reported by "time" takes into account the total amount of address space that is consumed by an allocation. What you see as a factor of 2 overestimation of the space allocated is simply due to the fact that the memory manager is based on a Cheney style collector which performs the copy phase using a fromspace and a tospace. When X bytes are reserved for an object in the fromspace there is implicitly X bytes in the tospace that are reserved for copying the object to the tospace (in the eventuality that the object survives the next collection cycle). It is debatable whether this is the "correct" way of reporting the amount of storage allocated. I think it is correct because it takes into account the implementation of the memory manager (including unused space allocated for alignment reasons, size of the header, the fromspace/tospace strategy). It is also possible to see when a object is allocated as a "still" object managed by the mark-sweep collector (this occurs for example for large objects) :
(define dummy (time (make-u8vector 1000)))
(time (make-u8vector 1000)) 0 ms real time 0 ms cpu time (0 user, 0 system) no collections 2008 bytes allocated 1 minor fault 1 major fault
(define dummy (time (make-u8vector 1000000)))
(time (make-u8vector 1000000)) 2 ms real time 1 ms cpu time (1 user, 0 system) 1 collection accounting for 0 ms real time (0 user, 0 system) 1000024 bytes allocated 248 minor faults no major faults
The first call to make-u8vector allocates in the fromspace of the copying collector a u8vector of length 1000 bytes. It shows up as 2008 bytes allocated because there is a 4 byte header, and the same space is reserved in the tospace.
The second call to make-u8vector creates a large object. It allocates a u8vector of length 1000000 as a "still" object in the heap managed by the mark-sweep collector. In this case the u8vector has a 24 byte header (6 machine 32 bit words) followed by 1000000 bytes containing the elements of the u8vector.
Marc
On 2012-12-21, at 12:50 AM, Bradley Lucier lucier@math.purdue.edu wrote:
On my 64-bit Mac, I get
(time (##make-vector 8))
(time (##make-vector 8)) 0 ms real time 0 ms cpu time (0 user, 0 system) no collections 144 bytes allocated 1 minor fault no major faults #(0 0 0 0 0 0 0 0)
I'd figure this allocates only 8 (header) + 8 (words) * 8 (bytes/word) = 72 bytes, but time is reporting 144.
Similarly (and what led me to this),
(time (##bignum.make 2 #f #f))
(time (##bignum.make 2 #f #f)) 0 ms real time 0 ms cpu time (0 user, 0 system) no collections 48 bytes allocated no minor faults no major faults
(don't do this at home!), which I expect allocates 8 (header) + 2 (adigits) * 8 (bytes/adigit) = 24 bytes.
What am I not understanding?
More generally, can the number of bytes reported be confused by stack manipulation? I.e., if things go on the stack, but then the stack is unwound, does "time" report any allocation?
Thanks.
Brad
On Dec 21, 2012, at 9:20 AM, Marc Feeley wrote:
<lots of helpful stuff>
Thanks. What about this more vague question:
More generally, can the number of bytes reported be confused by stack manipulation? I.e., if things go on the stack, but then the stack is unwound, does "time" report any allocation?
I'm writing some code that does not allocate anything, as far as I can tell from the GVM code, yet there is a report of 240 bytes allocated. Am I missing something?
Brad
On 2012-12-21, at 12:50 AM, Bradley Lucier lucier@math.purdue.edu wrote:
More generally, can the number of bytes reported be confused by stack manipulation? I.e., if things go on the stack, but then the stack is unwound, does "time" report any allocation?
"time" does report the space used by stack frames which migrate to the heap, but not those in the bounded size stack area. That's because stack frames are usually reclaimed when functions return and it would be confusing to the programmer trying to make sense of the space allocation reports.
In other words, the space allocated for stack frames is ignored unless the stack area overflows (a deep recursion will cause the stack frames to migrate to the heap) or the current continuation is captured.
Here are some examples:
(declare (standard-bindings) (fixnum) (not safe))
(define (loop n thunk) (if (= n 0) (thunk) (+ 1 (loop (- n 1) thunk))))
(time (loop 10000 (lambda () 0))) ;; no bytes allocated (time (loop 11000 (lambda () 0))) ;; no bytes allocated (time (loop 12000 (lambda () 0))) ;; no bytes allocated (time (loop 13000 (lambda () 0))) ;; no bytes allocated (time (loop 14000 (lambda () 0))) ;; no bytes allocated (time (loop 15000 (lambda () 0))) ;; 917120 bytes allocated (time (loop 16000 (lambda () 0))) ;; 917504 bytes allocated
(time (loop 100 (lambda () (##continuation-capture list) 0))) ;; 6768 bytes allocated (time (loop 1000 (lambda () (##continuation-capture list) 0))) ;; 64368 bytes allocated (time (loop 10000 (lambda () (##continuation-capture list) 0))) ;; 640368 bytes allocated (time (loop 100000 (lambda () (##continuation-capture list) 0))) ;; 6402608 bytes allocated
Marc