[iolib-devel] crash with the current iolib
Hi, First I want to thank you for your great effort. I tried to stress the current iolib. Attached is a simple HTTP reply generator. I used sbcl 1.0.5 VM on a 32 bit AMD desktop machine. I used siege with lot's of concurrent connections. Here is the first inspection: This is my stupid test server with current iolib (with a small content size). aycan@zen ~ $ siege -b -c10 -t5S http://localhost:8001/ ** siege 2.61 ** Preparing 10 concurrent users for battle. The server is now under siege... Lifting the server siege.. done. Transactions: 6996 hits Availability: 100.00 % Elapsed time: 4.86 secs Data transferred: 615648 bytes Response time: 0.01 secs Transaction rate: 1439.51 trans/sec Throughput: 126676.54 bytes/sec Concurrency: 9.53 Successful transactions: 6996 Failed transactions: 0 Longest transaction: 4.25 Shortest transaction: 0.00 I got 1490 transactions per second. The performance is great (I got around 500 trans/sec with a threaded version) but when I repeat the test, SBCL crashes silently and eats all my cpu. I don't get any errors or some output. Also the :timeout parameter to add-fd should not be nil by default, if so I got type errors with lengthy content sizes. Here is the same siege parameters applied to *apache-tomcat-6-0-13* (the content size is around 7600 bytes): aycan@zen ~ $ siege -b -c100 -t5S http://localhost:8080/ ** siege 2.61 ** Preparing 100 concurrent users for battle. The server is now under siege... Lifting the server siege.. done. Transactions: 16083 hits Availability: 100.00 % Elapsed time: 6.71 secs Data transferred: 118274382 bytes Response time: 0.00 secs Transaction rate: 2396.87 trans/sec Throughput: 17626584.40 bytes/sec Concurrency: 10.63 Successful transactions: 16083 Failed transactions: 0 Longest transaction: 4.18 Shortest transaction: 0.00 Is it possible to outperform java io performance? -- aycan -- Aycan iRiCAN C0R3 Computer Security Group http://people.core.gen.tr/~aycan.irican/ (in-package :asdf) (eval-when (:compile-toplevel :load-toplevel) (asdf:oos 'asdf:load-op 'iolib)) (defpackage :iolib-problem (:use #:common-lisp #:net.sockets #:iomux)) (in-package :iolib-problem) (defparameter *server* nil) (defparameter *event-base* (make-instance 'iomux:event-base)) (defparameter *event-loop-thread* nil) (defparameter *server-event* nil) (defun handle-connection (sock handler) (unwind-protect (progn (funcall handler sock) (finish-output sock)) (close sock))) (defun make-server (port) (let ((sock (create-socket :address-family :internet :type :stream :connect :passive :ipv6 nil))) (bind-address sock +ipv4-unspecified+ :port port) (socket-listen sock) sock)) (defun add-connection-handler (event-base connection request-handler) (let ((handle)) (labels ((close-handler () (remove-event event-base handle) (close connection)) (handler (fd evtype) (declare (ignorable fd)) (handler-case (cond ((eq evtype :read) (funcall request-handler connection) (close-handler)) (t (close-handler))) (condition (c) (declare (ignorable c)) (describe c))) )) (setf handle (iomux:add-fd event-base (sockets::socket-fd connection) :read #'handler :persistent t :timeout 1))))) (defun add-single-threaded-server (event-base listener-socket request-handler) (labels ((handler (fd evtype) (declare (ignorable fd)) (case evtype (:read (let ((connection (accept-connection listener-socket))) (add-connection-handler event-base connection request-handler))) (:otherwise (break))))) (iomux::add-fd event-base (sockets::socket-fd listener-socket) :read #'handler :persistent t :timeout 1))) (defun start-server (port) (setf *server* (make-server port)) (setf *server-event* (add-single-threaded-server *event-base* *server* #'test-handler)) (event-dispatch *event-base*)) (defun stop-server () (close *server*) (remove-event *event-base* *server-event*) (setf *server* nil) (setf *server-event* nil)) (defparameter *response-body* "<HTML><HEAD><TITLE>Test</TITLE></HEAD><BODY>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</BODY></HTML>") (defparameter *response-header* (format nil "HTTP/1.1 200 OK~%Content-Type: text/html~%Content-Length: ~A~%" (length *response-body*))) (defun test-handler (sock) (format sock "~A~%~A" *response-header* *response-body*))
On Mon, Jun 04, 2007 at 01:04:13PM +0300, Aycan iRiCAN wrote:
Hi,
First I want to thank you for your great effort. I tried to stress the current iolib. Attached is a simple HTTP reply generator. I used sbcl 1.0.5 VM on a 32 bit AMD desktop machine. I used siege with lot's of concurrent connections. Here is the first inspection: I've attached your code which I modified a bit in order to be able to debug it more easily
I got 1490 transactions per second. The performance is great (I got around 500 trans/sec with a threaded version) but when I repeat the test, SBCL crashes silently and eats all my cpu. I don't get any errors or some output. it crashes here too with the latest SBCL, with a memory-fault-error(most of the time, I also got various types of heap corruption) - I had to run SBCL directly from the terminal because indeed Slime seems not to be able to cope with a memory fault in the REPL thread. On my computer SBCL crashed directly if I run the test for just 7 seconds I've also tried CMUCL which is a bit sturdier(but essentially it crashes too), while CLISP had no problems(although it is slower that SBCL or CMUCL):
Also the :timeout parameter to add-fd should not be nil by default, if so I got type errors with lengthy content sizes. I believe that it's better if the users of the library specify
hechee@blackhole iolib $ siege -b -c10 -t400S http://localhost:8001/ ** siege 2.65 ** Preparing 10 concurrent users for battle. The server is now under siege... Lifting the server siege... done. Transactions: 216139 hits Availability: 100.00 % Elapsed time: 400.81 secs Data transferred: 30.30 MB Response time: 0.02 secs Transaction rate: 539.26 trans/sec Throughput: 0.08 MB/sec Concurrency: 9.95 Successful transactions: 216139 Failed transactions: 0 Longest transaction: 9.06 Shortest transaction: 0.00 themselves the timeout both for the simplicity of the library code and for the fact that it's difficult to select a default timeout that is ok for everyone
Is it possible to outperform java io performance? once the features will all be implemented and we get to optimize the code, I think it can certainly be done
-- (sign :name "Stelian Ionescu" :aka "fe[nl]ix" :quote "Quidquid latine dictum sit, altum videtur.")
participants (2)
-
Aycan iRiCAN
-
Stelian Ionescu