Forth to the past - qsort
I see some things that could be improved with this code.

Fix exetime

The exetime word is defined like this:

: exetime  utime 2&gt;r quicksort execute  utime 2r&gt; d- ." dtime " . cr ;


There are a number of problems with that.  First, the formatting is not very good.  I'd prefer to see a stack comment, for example.  Second, this should probably take a parameter so that any word can be timed (this appears to be the intent from run).  Third, that last . should be d. to display the entire delta time rather than just half of it.

: exetime  ( fp -- ) 
   utime 2&gt;r  execute  utime 2r&gt; d- ." dtime " d. cr 
;


Use smaller words

Again using exetime as an example, there are actually two things done by the word as defined.  The first is that it calculates a delta time, and the second is that it prints that time.  I'd make those separate words.

Follow Forth convention

It's common to use prefixes to simplify code.  For example, everywhere ssrt is used, it's followed by @.  For that reason, I'd define and use word like these:

: @ssrt ssrt @ ;
: @size size @ ;
: !size size ! ;


Define and use common idioms

A number of cases in the code there is a sequence like this: size @ . but there is a common idiom for that and it's built in to many Forth implementations.  If it's not, it's easy to define:

: ?  ( a -- )   @ . ;


It would be used like this:  size ?.  Alternatively, one could use the prefix idiom which is associated with a particular value:

: ?size  ( -- )   size @ . ;


Eliminate unused variables

The logs variable is defined but never used.  This needlessly clutters the code.

Simplify control structure

Instead of using begin .. while .. repeat, it's often the case that one can use begin .. until instead and simplify the code.  Using the refactored smaller words as suggested above, here's what run looks like now:  

: run ( fp )
    &gt;r
    begin 
        copy-array
        array-limits r@ exetime
        ." size " ?size ." dtime " d. cr
    size2x total-size &gt; until
    rdrop
;


These are the refactored words:

: exetime  ( fp -- ) utime 2&gt;r execute utime 2r&gt; d- ;
: copy-array ( -- ) data @ ssrt @ size @ cells move ;
: array-limits ( -- alo ahi ) ssrt @ dup size @ cells + swap ;
: @size ( -- n ) size @ ;
: ?size ( -- ) @size . ;
: size2x ( -- n ) size @ 2 * dup size ! ;


Make sure comments don't lie

The shuffle word starts like this:

: shuffle ( n a -- )


However, that's not correct.  It should instead be:

: shuffle ( n1 n2 a -- )


Use refactoring to improve speed

The code currently contains this:

: median_of_3 ( n0 n1 n2 -- n )
    &gt;r 2dup &gt; if swap then
    r&gt; 2dup &gt; if swap then drop
       2dup &lt; if swap then drop
;


However, in addition to being somewhat opaque, it's not as fast as it could be.  Refactoring into smaller chunks improves both readability and speed:

\ arrange top two stack values to assure n0 &lt;= n1
: lohi ( n0 n1 -- n0 n1 ) 2dup &gt; if swap then ;
\ arrange top three stack values to assure n0 &lt;= n1 &lt;= n2
: 3sort ( n0 n1 n2 -- n0 n1 n2 ) lohi &gt;r lohi r&gt; lohi ;
\ extract median value from top 3 items on stack
: median_of_3 ( n0 n1 n2 -- n1 ) 3sort drop nip ; 


Be aware of non-standard extensions

The code uses the non-standard extensions: 

 rdrop -rot utime 


It is not hard to write replacements for the first two if needed:

: rdrop r&gt; drop ;
: -rot rot rot ;


Since utime is only used in the test code, perhaps it's not as critical.  There is no standard replacement.