From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Tomas Hlavaty Newsgroups: gmane.emacs.help Subject: Re: Identifying sources of allocations in a toy Mandelbrot package Date: Sat, 27 Jan 2024 00:36:41 +0100 Message-ID: <87wmrvd5va.fsf@neko.mail-host-address-is-not-set> References: <87v87ps5gn.fsf@neko.mail-host-address-is-not-set> <877ck4wev2.fsf@neko.mail-host-address-is-not-set> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32524"; mail-complaints-to="usenet@ciao.gmane.io" Cc: help-gnu-emacs@gnu.org, incal@dataswamp.org, Eli Zaretskii To: Psionic K Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sat Jan 27 00:37:35 2024 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rTVlP-0008K1-C8 for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 27 Jan 2024 00:37:35 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rTVkq-00060q-9R; Fri, 26 Jan 2024 18:37:00 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rTVkp-00060i-1G for help-gnu-emacs@gnu.org; Fri, 26 Jan 2024 18:36:59 -0500 Original-Received: from logand.com ([37.48.87.44]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rTVkn-0000xV-AM; Fri, 26 Jan 2024 18:36:58 -0500 Original-Received: by logand.com (Postfix, from userid 1001) id 58EF819E873; Sat, 27 Jan 2024 00:36:46 +0100 (CET) X-Mailer: emacs 28.2 (via feedmail 11-beta-1 I) In-Reply-To: Received-SPF: pass client-ip=37.48.87.44; envelope-from=tom@logand.com; helo=logand.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:145809 Archived-At: --=-=-= Content-Type: text/plain On Sat 20 Jan 2024 at 19:03, Psionic K wrote: > I was mainly hoping to start identifying forms that can do okay even > in spite of the Elisp runtime, especially for these kind of iteration > problems that could - but should not - generate lots of garbage. The > first rows go by in the blink of an eye because of the cache locality. > Elisp is almost something. The memory pathologies are likely > affecting every other perceived lack of responsiveness. I was curious about: - How does native compilation improve things? - How does fixed point arithmetic improve things? Run: (benchmark-run 1 (mandelbrot)) with the attached mandelbrot1.el (floating point): after emacs-lisp-native-compile-and-load: => (120.40541861 1947 93.45048212499998) after emacs-lisp-byte-compile-and-load: => (128.362728323 1942 93.44881820700004) with the attached mandelbrot.el (fixed point): after emacs-lisp-native-compile-and-load: (32.898215598 2 0.09366582000001245) after emacs-lisp-byte-compile-and-load: (51.629763289 2 0.09165389300000015) For comparison, the attached forth version test.fs takes about 6sec. I find it interesting that: - native compilation improves so little compared to byte compilation. - floating point calculations are very slow. - emacs-lisp is very slow --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=mandelbrot1.el Content-Transfer-Encoding: quoted-printable ;;; -*- lexical-binding: t -*- (defun mandelbrot1 (cx cy) (let ((zr 0) (zi 0) (v 0)) (while (and (< v 256) (<=3D (+ (* zr zr) (* zi zi)) 4)) (setq v (1+ v)) (let ((tmp (+ (* zr zr) (- (* zi zi)) cx))) (setq zi (+ (* (* zr zi) 2) cy)) (setq zr tmp))) ;; samples that hit 256 wrap in the graphic to display as zero ;; exponential 0.8 enhances contrast a bit (floor (* 256 (expt (/ v 256.0) 0.8))))) (defun mandelbrot (&optional w h) (interactive) (pop-to-buffer (get-buffer-create "*mandelbrot*")) (fundamental-mode) (erase-buffer) (set-buffer-multibyte nil) (let (;;(gc-cons-threshold (* 800000 2048)) ;;(gc-cons-percentage 1.0) (inhibit-modification-hooks t) (w (or w 1600)) (h (or h 1200)) (x0 -2.5) (y0 -1.5) (dx 4.0) (dy 3.0)) (insert (format "P6\n%d %d\n255\n" w h)) (let ((dxp (/ dx w)) (dyp (/ dy h))) (dotimes (y h) (let ((cy (+ y0 (* dyp y)))) (dotimes (x w) (let ((v (mandelbrot1 (+ x0 (* dxp x)) cy))) (insert v v v))))))) (image-mode) t) ;;(mandelbrot 320 200) ;;(mandelbrot 640 480) ;;(mandelbrot 1024 768) ;;(mandelbrot) ;;(profiler-start 'mem) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu+mem) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu+mem) ;;(mandelbrot) ;;(profiler-stop) ;;(profiler-report) ;;(benchmark-run 1 (mandelbrot)) ;;(120.40541861 1947 93.45048212499998) ;;(128.362728323 1942 93.44881820700004) --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=mandelbrot.el Content-Transfer-Encoding: quoted-printable ;;; -*- lexical-binding: t -*- ;; samples that hit 256 wrap in the graphic to display as zero ;; exponential 0.8 enhances contrast a bit (let ((a (make-vector 257 0))) (dotimes (v 256) (aset a v (floor (* 256 (expt (/ v 256.0) 0.8))))) (defun contrast (v) (aref a v))) (defconst +1fx+ (expt 2 12)) (defun fx (x) (* x +1fx+)) (defun fx2 (n d) (/ (* n +1fx+) d)) (defconst +4fx+ (fx 4)) (defun fx* (l r) (/ (* l r) +1fx+)) (defun fx^2 (x) (fx* x x)) (defun mandelbrot1 (cx cy) (let ((zr 0) (zi 0) (v 0) zr^2 zi^2) (while (and (< v 256) (<=3D (+ (setq zr^2 (fx^2 zr)) (setq zi^2 (fx^2 z= i))) +4fx+)) (setq v (1+ v)) (let ((tmp (+ zr^2 (- zi^2) cx))) (setq zi (+ (* (fx* zr zi) 2) cy)) (setq zr tmp))) v)) (defun mandelbrot (&optional w h) (interactive) (pop-to-buffer (get-buffer-create "*mandelbrot*")) (fundamental-mode) (erase-buffer) (set-buffer-multibyte nil) (let (;;(gc-cons-threshold (* 800000 2048)) ;;(gc-cons-percentage 1.0) (inhibit-modification-hooks t) (w (or w 1600)) (h (or h 1200)) (x0 (fx2 -25 10)) (y0 (fx2 -15 10))) (insert (format "P6\n%d %d\n255\n" w h)) (let ((dxp (/ (fx 4) w)) (dyp (/ (fx 3) h))) (dotimes (y h) (let ((cy (+ y0 (* dyp y)))) (dotimes (x w) (let ((v (contrast (mandelbrot1 (+ x0 (* dxp x)) cy)))) (insert v v v))))))) (image-mode) t) ;;(mandelbrot 320 200) ;;(mandelbrot 640 480) ;;(mandelbrot 1024 768) ;;(mandelbrot) ;;(profiler-start 'mem) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu+mem) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu) ;;(mandelbrot 320 200) ;;(profiler-stop) ;;(profiler-report) ;;(profiler-start 'cpu+mem) ;;(mandelbrot) ;;(profiler-stop) ;;(profiler-report) ;;(benchmark-run 1 (mandelbrot)) ;;(32.898215598 2 0.09366582000001245) ;;(51.629763289 2 0.09165389300000015) --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=test.fs \ (compile "time gforth test.fs >a.pnm") 1 16 lshift constant 1fx : fx ( n -- fx ) 1fx * ; : fx2 ( n1 n2 -- fx ) 1fx swap */ ; : fx* ( fx1 fx2 -- fx3 ) 1fx */ ; : fx^2 ( fx -- fx ) dup fx* ; 1600 constant w 0 value cx 1200 constant h 0 value cy -25 10 fx2 constant x0 0 value zr -15 10 fx2 constant y0 0 value zi 4 fx w / constant dxp 0 value v 3 fx h / constant dyp : cx! ( n -- ) dxp * x0 + to cx ; : cy! ( n -- ) dyp * y0 + to cy ; : nl newline type ; : p6 ." P6" nl w . h . nl 255 . nl ; : rgb ( n -- ) dup emit dup emit emit ; \ : expt ( r1 r2 -- r3 ) fexp fswap fln f* ; : mandelbrot1 ( -- n ) 0 to v 0 to zr 0 to zi begin v 256 < ( f -- ) zr fx^2 zi fx^2 + [ 4 fx ] literal <= ( f1 f2 -- ) and while v 1+ to v zr fx^2 zi fx^2 - cx + ( fx -- ) zr zi fx* 2* cy + to zi to zr repeat \ samples that hit 256 wrap in the graphic to display as zero \ exponential 0.8 enhances contrast a bit v \ s>f 256e f/ 0.8e expt 256e f* floor f>s ; : dot mandelbrot1 rgb ; : row w 0 do i cx! dot loop ; : mandelbrot h 0 do i cy! row loop ; p6 mandelbrot bye --=-=-=--