;;;-*- Mode:LISP; Package:BENCH-FFTU; Base:8 -*- ;;; From the "Dick Gabriel" Benchmark Series. ;;; Enhancements (C) Copyright 1983, Lisp Machine, Inc. (EVAL-WHEN (EVAL COMPILE LOAD) (DEFCONST *TO-UCOMPILE* '(FFT)) (MAPC #'(LAMBDA (X) (PUTPROP X T 'COMPILER:MICROCOMPILE) (PUTPROP X T ; ':DYNAMIC ':DEPEND-ON-BEING-MICROCOMPILED)) *TO-UCOMPILE*)) ;;;BEGIN ;;;FFT ;Barrow FFT ;Here is the Barrow FFT benchmark which tests floating operations ;of various types, including flonum arrays. (ARRAYCALL FLONUM A I) ;accesses the I'th element of the FLONUM array A, where these arrays are ;0-based. (STORE (ARRAYCALL FLONUM A I) V) stores the value V in the ;I'th element of the FLONUM array A. ;There was a fair amount of FLONUM GC's in the SAIL MacLisp run, which, ;when it needed to CORE up during GC, took 4.5 seconds of CPU time for the ;computation and 15 seconds for GC. Other configurations of memory required ;only 1.5 seconds for GC. ;Refer to this as FFT. ; -rpg- (DEFMACRO AREF$ (A &REST L) #+MACLISP `(ARRAYCALL FLONUM ,A ,@L) #-MACLISP `(AREF ,A ,@L)) ;;; *-*lisp*-* ;;; From Rich Duda, by way of Harry Barrow -- 3/26/82 (DEFUN FFT ;Fast Fourier Transform (AREAL AIMAG smallp) ;AREAL = real part (PROG ;AIMAG = imaginary part (AR AI PIE I J K M N LE LE1 IP NV2 NM1 UR UI WR WI TR TI) (declare (fixnum I J K M N LE LE1 IP NV2 NM1)) (SETQ AR (PROGN AREAL)) ;Initialize (SETQ AI (PROGN AIMAG)) (SETQ PIE (if smallp 3.14159265s00 3.141592653589793)) (SETQ N (CADR (ARRAYDIMS AR))) (SETQ N (1- N)) (SETQ NV2 (// N 2)) (SETQ NM1 (1- N)) (SETQ M 0) ;Compute M = log(N) (SETQ I 1) L1 (COND ((< I N)(SETQ M (1+ M))(SETQ I (+ I I))(GO L1))) (COND ((NOT (EQUAL N (^ 2 M))) (ERROR "array size not a power of two."))) (SETQ J 1) ;Interchange elements (SETQ I 1) ;in bit-reversed order L3 (COND ((the fixnum (< I J)) (SETQ TR (AREF$ AR J)) (SETQ TI (AREF$ AI J)) (SETF (AREF$ AR J) (AREF$ AR I)) (SETF (AREF$ AI J) (AREF$ AI I)) (SETF (AREF$ AR I) TR) (SETF (AREF$ AI I) TI))) (SETQ K NV2) L6 (COND ((the fixnum (< K J)) (SETQ J (the fixnum (- J K))) (SETQ K (// K 2)) (GO L6))) (SETQ J (the fixnum (+ J K))) (SETQ I (the fixnum (1+ I))) (COND ((the fixnum (< I N))(GO L3))) (DO L 1 (the fixnum (1+ L)) (the fixnum (> L M)) ;Loop thru stages (declare (fixnum l)) (SETQ LE (^ 2 L)) (SETQ LE1 (// LE 2)) (SETQ UR (if smallp 1.0s00 1.0)) (SETQ UI (if smallp 0.0s00 0.0)) (SETQ WR (COS (//$ PIE (if smallp (small-float le1) (FLOAT LE1))))) (SETQ WI (SIN (//$ PIE (if smallp (small-float le1) (FLOAT LE1))))) (DO J 1 (the fixnum (1+ J)) (the fixnum (> J LE1)) ;Loop thru butterflies (DO I J (the fixnum (+ I LE)) (> I N) ;Do a butterfly (SETQ IP (+ I LE1)) (SETQ TR (-$ (*$ (AREF$ AR IP) UR) (*$ (AREF$ AI IP) UI))) (SETQ TI (+$ (*$ (AREF$ AR IP) UI) (*$ (AREF$ AI IP) UR))) (SETF (AREF$ AR IP) (-$ (AREF$ AR I) TR)) (SETF (AREF$ AI IP) (-$ (AREF$ AI I) TI)) (SETF (AREF$ AR I) (+$ (AREF$ AR I) TR)) (SETF (AREF$ AI I) (+$ (AREF$ AI I) TI))) (SETQ TR (-$ (*$ UR WR) (*$ UI WI))) (SETQ TI (+$ (*$ UR WI) (*$ UI WR))) (SETQ UR TR) (SETQ UI TI))) (RETURN T))) ;;; Sets up the two arrays (DECLARE (SPECIAL *RE* *IM*)) (SETQ *RE* (*ARRAY NIL 'FLONUM 1025.)) (SETQ *IM* (*ARRAY NIL 'FLONUM 1025.)) ;;; The timer which does 10 calls on FFT ;(include "timer.lsp") (defconst *ucode-loaded? nil) (defun load-ucode () (apply #'compiler:ma-load *to-ucompile*) (setq *ucode-loaded? t)) (timer timit (if *ucode-loaded? (do ((ntimes 0 (1+ ntimes))) ((= ntimes 10.)) (fft *re* *im* nil)) "ucode not loaded")) (defun test (n) (dotimes (i n) (fft *re$* *im$* t))) (DEFVAR *RE$* (make-array 1025. ':initial-value 0.0s00)) (DEFVAR *IM$* (make-array 1025. ':initial-value 0.0s00)) (timer timit$ (if *ucode-loaded? (do ((ntimes 0 (1+ ntimes))) ((= ntimes 10.)) (fft *re$* *im$* t)) "ucode not loaded")) ;;;END