2

我在 Windows 7 上使用 Clozure-CL。我为测试编写了一个简单的“图像”类(嗯,结构)。

(defmacro -> (struct slot) `(slot-value ,struct ,slot))

(defstruct 
  (image 
    (:constructor make-image (&key width height (bytes-per-pixel 4) 
        (pixels (make-array (* bytes-per-pixel (* width height))
                                :element-type '(unsigned-byte 8)))))
    (:print-function (lambda (img s k)
                       (declare (ignore k)) 
               (format s "image(~ax~a@~abpp)"
                               (-> img 'width) (-> img 'height)
                               (* 8 (-> img 'bytes-per-pixel))))))
  (width 0 :type '(unsigned-byte 32))
  (height 0 :type '(unsigned-byte 32))
  (bytes-per-pixel 4 :type '(unsigned-byte 32))
  (pixels nil))

不幸的是,当我尝试这样做时:

(make-image :width 2048 :height 2048)

我收到此错误:

value 16777216 is not of the expected type (UNSIGNED-BYTE 24).
   [Condition of type TYPE-ERROR]

这是堆栈跟踪(从 slimv 复制粘贴):

  0: (CCL::MAKE-UARRAY-1 207 16777216 NIL NIL NIL NIL NIL NIL NIL 16777216)
  1: (MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048 :BYTES-PER-PIXEL 4 :PIXELS 16777216)
  2: (CCL::CALL-CHECK-REGS MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048)
  3: (CCL::CHEAP-EVAL (MAKE-IMAGE :WIDTH 2048 :HEIGHT 2048))
  4: (SWANK::EVAL-REGION "(make-image :width 2048 :height 2048)\n")
  5: ((:INTERNAL SWANK::REPL-EVAL))
  6: (SWANK::TRACK-PACKAGE #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56EAE>)
  7: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56EFE>)
  8: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #x19D56F26>)
  9: (SWANK::REPL-EVAL "(make-image :width 2048 :height 2048)\n")
 10: (CCL::CALL-CHECK-REGS SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n")
 11: (CCL::CHEAP-EVAL (SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n"))
 12: (SWANK:EVAL-FOR-EMACS (SWANK:LISTENER-EVAL "(make-image :width 2048 :height 2048)\n") "GAME" 135)
 13: (SWANK::PROCESS-REQUESTS NIL)
 14: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 15: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 16: (SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK #<Compiled-function SWANK:SWANK-DEBUGGER-HOOK #x186F1EF6> #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::HANDLE-REQUESTS) #x1882D666>)
 17: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #<SWANK-BACKEND::SLIME-OUTPUT-STREAM #x188247CE>) (*STANDARD-INPUT* . #<SWANK-BACKEND::SLIME-INPUT-STREAM #x188249DE>) ..))) #<CCL:COMPILED-LEXICAL-CLO..
 18: (SWANK::HANDLE-REQUESTS #<MULTITHREADED-CONNECTION  #x1880CB0E> NIL)
 19: (CCL::RUN-PROCESS-INITIAL-FORM #<PROCESS repl-thread(12) [Active] #x18824C8E> (#<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #x18824B46>))

据我了解,Clozure-CL 使用一些内部函数来制作字节数组,并且出于某种原因,该函数需要 24 位整数参数作为数组大小,并且因为 16777216 是 2 24,它不适合 24 位整数。我想取消这个限制。我该如何解决这个问题?

编辑

我检查了文档,发现在 32 位 Clozure-CL 上,最大数组大小限制 ( array-total-size-limit) 是(expt 2 24). 64 位版本的限制要大得多,但是,我可以做些什么吗?

4

1 回答 1

2

正如您已经发现的那样,这是 32 位 Clozure CL 版本的限制。64 位 Clozure CL 版本有更大的限制。

在我的 Mac 上:

? array-total-size-limit
72057594037927936

你能做什么:

  • 使用几个较小的数组并将其隐藏在某个界面后面。痛苦。
  • 使用 FFI 在 C 端分配数组。有点痛。确保您有一些类型/边界检查并正确进行内存管理。
  • 使用 64 位版本。也许这对你来说是一个选择?

32 位版本的实现限制不容易改变,如果有的话。

于 2013-08-21T11:32:21.453 回答