[Openmcl-devel] memory

Gary Byers gb at clozure.com
Wed Apr 14 15:45:11 PDT 2010

Hmm.  So one SIZEOF doesn't fit all ?

There are other names that one could use, but one convention (used
in the function HEAP-UTILIZATION and elsewhere) is to call "the size,
in bytes, of the accessible data in an object" its LOGICAL-SIZE
and the the size of the data + any header + alignment its PHYSICAL-SIZE.

You could also make one function that returns two values, or otherwise
structure this differently.

(in-package "CCL")

(defun logical-sizeof (thing)
   ;; All memory-allocated objects in CCL are either CONSes or
   ;; "UVECTOR"s; a UVECTOR contains a header which describes the
   ;; object's primitive type (represented as an (UNSIGNED-BYTE 8) and
   ;; accessible via the function CCL::TYPECODE) and element-count
   ;; (accessible via the function CCL::UVSIZE.)  A function defined in
   ;; the compiler backend knows how to map from a typecode and
   ;; element-count to a size in octets.
   ;; On x86-64, SYMBOLs and FUNCTIONs have their own tag, but there's
   ;; an underlying UVECTOR.
   (cond ((null thing) 0)
         ((consp thing) target::cons.size)
         #+x8664-target ((and thing (symbolp thing)) (logical-sizeof (%symptr->symvector thing)))
         #+x8664-target ((functionp thing) (logical-sizeof (function-to-function-vector thing)))
         ((uvectorp thing)
          (let* ((typecode (typecode thing))
                 (element-count (uvsize thing)))
            ;; Call the architecture-specific backend function.
            (funcall (arch::target-array-data-size-function
                            (backend-target-arch *host-backend*))
                           typecode element-count)
                           typecode element-count))
         (t 0)))

(defun physical-sizeof (thing)
   ;; For non-uvectors, the physical size is the same as the logical size.
   ;; For uvectors, the physical size includes header & alignment overhead.
   ;; On x8664, SYMBOLs and FUNCTIONs are conceptually uvevtors, but have
   ;; their own tag; we map them to the underlying uvector in the cond.
   (let* ((logical-size (logical-sizeof thing)))
     #+x8664-target ((and thing (symbolp thing)) (physical-sizeof (%symptr->symvector thing)))
     #+x8664-target ((functionp thing) (physical-sizeof (function-to-function-vector thing)))
     ((uvectorp thing)
       ;; if thing is a UVECTOR, account for header and alignment,
       (logandc2 (+ logical-size
                    target::node-size ; size of header
                    (1- target::dnode-size)) ; alignment
                  (1- target::dnode-size)))
      (t logical-size))))

On Thu, 15 Apr 2010, Toomas Altosaar wrote:

>> Message: 5
>> Date: Wed, 14 Apr 2010 15:23:44 +0100
>> From: Tim Bradshaw <tfb at tfeb.org>
>> Subject: Re: [Openmcl-devel] memory
>> To: Alexander Repenning <ralex at cs.colorado.edu>
>> Cc: openmcl-devel Devel <openmcl-devel at clozure.com>
>> Message-ID: <BC113436-4CA0-4C0F-9BBA-106E7425DC6F at tfeb.org>
>> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
>> On 14 Apr 2010, at 14:58, Alexander Repenning wrote:
>>>  2) sizeof as C/C++/Ojective-C inspired sizeof operator returning the
>>>  number of RAW bytes with no meta information (no headers, no tag
>>>  bits, ...) typically used to deal with FFIs. Mostly used in the
>>>  context of allocating raw memory and accessing it with (%get-
>>>  byte ...) kinds of functions.This is what we need to interface with
>>>  OpenGL/ Cocoa and other APIs on Macs and PCs.
>> How is this useful?
> Let's say you want to copy some data from the Lisp to a framework
> you've written in C. For this you need to know how many 8 bit bytes
> need to be reserved on the heap. You do not want to include Lisp
> overhead.
>> I want SIZEOF to tell me how many instances of an
>> x I can fit in y bytes of memory, not some number which tells me
>> something I can't see a use for.
> Others can see a very definite use for it.
>> For this version of sizeof, what would, say (sizeof (make-
>> instance ...)) be useful for?
> I can envision many.
> For example, the same as above: take the case where you wish to
> mirror all the non-LISP specific implementation data in your instance
> through an FFI to and from a framework. This version will give you a
> lower bound as to how much memory requires reserving.
> Another example: let's say you wish to estimate how much
> memory/bandwidth/time is required for the serialization of a compound
> Lisp object between two (LISP) nodes located in remote locations on
> some network, assuming already that the other node is running the
> same version and has the same class definitions on hand. Without
> knowing the RAW number of bytes you will not be able to make an
> estimate.
>> Perhaps your objection is that this thing should not be called sizeof
>> because it's too reminiscent of the C function.
> I would object as well; it is much easier to expect a similarly named
> function to do the same thing across languages than to remember the
> differences.
> I don't think it should be too much of a strain on LISP users to come
> up with a more descriptive and more suitable name than what is used
> in C.
> This function's operation - whatever it will be called - is
> definitely implementation and version specific.
> Memory-footprint, Lisp-footprint, or something shorter and catchier?
> What do other LISP implementations call it?
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list