Re: [racket-users] C level bit manipulation - Racket Manifesto

2018-08-14 Thread David Brown
I think Racket handles this pretty well. The rule it defines is that a module 
cannot directly mutate another module's top-level symbols. This means that if a 
module itself does not contain any mutations of a top-level function, that 
definition cannot be changed at runtime. Therefore, everyone can rely on a 
simpler calling convention that doesn't require the extra level of indirection 
needed to handle changeable top-level symbols.

However, if the module contains a 'set!' or equivalent to a top-level symbol, 
then references to that symbol will have to be loaded each time, since it is 
possible for the value to change.

e.g.

#lang racket

(define (f1)
  (println "f1"))

(define (f2)
  (println "f2"))

;; The existence of the "set!" in this function means that 'f1' cannot be 
directly called, within or without this module.
(define (alter)
  (set! f1 f2))

(module+ main
  (f1)
  ; (set! f1 f2)   ;; Not allowed
  (alter) ;; Allowed
  (f2))

On 8/14/18, 7:51 AM, "Arthur Nunes-Harwitt"  wrote:

Hi,

   Racket seems to depricate redefinition of functions at run-time.  Since 
Racket isn't Scheme, why not prevent that and get back that performance?

-Arthur

==
Arthur Nunes-Harwitt
Computer Science Department, Rochester Institute of Technology
Room 70-3509
585-475-4916
==

"I don't know what the language of the future will be
called, but it will look like LISP."

This email is confidential and intended for the named recipient(s). In
the event the email is received by someone other than the recipient,
please notify the sender at a...@cs.rit.edu.

On Mon, 13 Aug 2018, George Neuner wrote:

>
> On 8/13/2018 10:02 AM, 'Paulo Matos' via Racket Users wrote
>> On 11/08/18 19:41, Sam Tobin-Hochstadt wrote:
>> > There are basically two differences between the `unsafe-lsb` function
>> > in Racket and the C one:
>> >  - the Racket calling convention vs the C calling convention
>> >  - the instruction used to perform the LSB calculation
>> > > For a variety of reasons Racket's function calling convention is more
>> > heavyweight than C's, but if that code is inlined into some larger
>> > function that will go away (as it would in C). The simpler instruction
>> > used by the C compiler is because the C compiler recognizes that
>> > pattern of bitwise and, whereas the Racket JIT does the obvious `and`.
>> > That could of course be fixed in the JIT, although it's not clear how
>> > much of a win it is. 
>> Is this something that will change with Racket-on-Chez? i.e. Racket will
>> then use the Chez optimizer to generate machine code?
>
> Racket's function call convention is heavier than C's because it has to 
deal 
> with the possibility that functions may be redefined at runtime, or may 
be 
> overloaded ... things C does not have to deal with.  The same function 
may 
> have multiple entry points depending on number of arguments, or presence 
of 
> keywords, etc.  And functions that may be redefined must be called 
indirectly 
> to avoid (re)patching every call site when/if the definition changes.  
These 
> things make (average) function calling in Racket slower than in C.
>
> It is expected that the Chez compiler will do a better job at optimizing 
> code, but it can't overcome differences in call semantics.  If you do 
> something "schemely" with your functions, then you WILL pay the price for 
it.
>
> George
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an 
email to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


smime.p7s
Description: S/MIME cryptographic signature


Re: [racket-users] C level bit manipulation - Racket Manifesto

2018-08-14 Thread Arthur Nunes-Harwitt

Hi,

  Racket seems to depricate redefinition of functions at run-time.  Since 
Racket isn't Scheme, why not prevent that and get back that performance?


-Arthur

==
Arthur Nunes-Harwitt
Computer Science Department, Rochester Institute of Technology
Room 70-3509
585-475-4916
==

"I don't know what the language of the future will be
called, but it will look like LISP."

This email is confidential and intended for the named recipient(s). In
the event the email is received by someone other than the recipient,
please notify the sender at a...@cs.rit.edu.

On Mon, 13 Aug 2018, George Neuner wrote:



On 8/13/2018 10:02 AM, 'Paulo Matos' via Racket Users wrote

On 11/08/18 19:41, Sam Tobin-Hochstadt wrote:
> There are basically two differences between the `unsafe-lsb` function
> in Racket and the C one:
>  - the Racket calling convention vs the C calling convention
>  - the instruction used to perform the LSB calculation
> > For a variety of reasons Racket's function calling convention is more
> heavyweight than C's, but if that code is inlined into some larger
> function that will go away (as it would in C). The simpler instruction
> used by the C compiler is because the C compiler recognizes that
> pattern of bitwise and, whereas the Racket JIT does the obvious `and`.
> That could of course be fixed in the JIT, although it's not clear how
> much of a win it is. 
Is this something that will change with Racket-on-Chez? i.e. Racket will

then use the Chez optimizer to generate machine code?


Racket's function call convention is heavier than C's because it has to deal 
with the possibility that functions may be redefined at runtime, or may be 
overloaded ... things C does not have to deal with.  The same function may 
have multiple entry points depending on number of arguments, or presence of 
keywords, etc.  And functions that may be redefined must be called indirectly 
to avoid (re)patching every call site when/if the definition changes.  These 
things make (average) function calling in Racket slower than in C.


It is expected that the Chez compiler will do a better job at optimizing 
code, but it can't overcome differences in call semantics.  If you do 
something "schemely" with your functions, then you WILL pay the price for it.


George

--
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an 
email to racket-users+unsubscr...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] C level bit manipulation - Racket Manifesto

2018-08-13 Thread George Neuner



On 8/13/2018 10:02 AM, 'Paulo Matos' via Racket Users wrote

On 11/08/18 19:41, Sam Tobin-Hochstadt wrote:
> There are basically two differences between the `unsafe-lsb` function
> in Racket and the C one:
>  - the Racket calling convention vs the C calling convention
>  - the instruction used to perform the LSB calculation
> 
> For a variety of reasons Racket's function calling convention is more

> heavyweight than C's, but if that code is inlined into some larger
> function that will go away (as it would in C). The simpler instruction
> used by the C compiler is because the C compiler recognizes that
> pattern of bitwise and, whereas the Racket JIT does the obvious `and`.
> That could of course be fixed in the JIT, although it's not clear how
> much of a win it is. 


Is this something that will change with Racket-on-Chez? i.e. Racket will
then use the Chez optimizer to generate machine code?


Racket's function call convention is heavier than C's because it has to 
deal with the possibility that functions may be redefined at runtime, or 
may be overloaded ... things C does not have to deal with.  The same 
function may have multiple entry points depending on number of 
arguments, or presence of keywords, etc.  And functions that may be 
redefined must be called indirectly to avoid (re)patching every call 
site when/if the definition changes.  These things make (average) 
function calling in Racket slower than in C.


It is expected that the Chez compiler will do a better job at optimizing 
code, but it can't overcome differences in call semantics.  If you do 
something "schemely" with your functions, then you WILL pay the price 
for it.


George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] C level bit manipulation - Racket Manifesto

2018-08-13 Thread 'Paulo Matos' via Racket Users



On 11/08/18 19:41, Sam Tobin-Hochstadt wrote:
> There are basically two differences between the `unsafe-lsb` function
> in Racket and the C one:
>  - the Racket calling convention vs the C calling convention
>  - the instruction used to perform the LSB calculation
> 
> For a variety of reasons Racket's function calling convention is more
> heavyweight than C's, but if that code is inlined into some larger
> function that will go away (as it would in C). The simpler instruction
> used by the C compiler is because the C compiler recognizes that
> pattern of bitwise and, whereas the Racket JIT does the obvious `and`.
> That could of course be fixed in the JIT, although it's not clear how
> much of a win it is.
> 

Is this something that will change with Racket-on-Chez? i.e. Racket will
then use the Chez optimizer to generate machine code?

> More broadly, whether Racket supports "C-level" programming depends on
> what you mean. If it means "can I use the same APIs and access the
> same bits I would in C", then you certainly can, although often you
> need to use the FFI to do so. That's what the Racket Manifesto means.

Understood, that's what I wanted to know.

> If it means "can I generate the same assembly instructions or get the
> same maximum performance from pure Racket code as from C code", then
> it isn't true, and you'll need to use some other tools, such as
> generating code yourself (see https://github.com/rjnw/sham for an
> example).
> 

Wow,didn't know about sham. Thanks for the reference.

> Sam
> 
> On Sat, Aug 11, 2018 at 4:15 AM, 'Paulo Matos' via Racket Users
>  wrote:
>> Hi,
>>
>> In http://felleisen.org/matthias/manifesto/, you can read:
>> "In support, Racket offers protection mechanisms to implement a full
>> language spectrum, from C-level bit manipulation to soundly typed
>> extensions."
>>
>> What are we talking about here when we mention C-level bit manipulation? Is
>> this referring to the ffi or some other Racket feature that allows me to
>> generate unsafe bit manipulation instructions?
>>
>> In C, for a bitwise_and of an integer x and 0xff, I get:
>> https://godbolt.org/g/gy3ZN9
>> bitwise_and:
>>   movzx eax, dil
>>   ret
>>
>> In Racket, I tried:
>> #lang racket
>>
>> (require disassemble
>>  racket/unsafe/ops)
>>
>> (define (lsb x)
>>   (bitwise-and x #xff))
>>
>> (disassemble lsb)
>>
>>0: 488b4808   (mov rcx (mem64+ rax #x8))
>>4: 48898bf8ff (mov (mem64+ rbx #x-8) rcx)
>>b: 488b4810   (mov rcx (mem64+ rax #x10))
>>f: 48898bf0ff (mov (mem64+ rbx #x-10) rcx)
>>   16: 4881c3f0ff (add rbx #xfff0)
>>   1d: 488b13 (mov rdx (mem64+ rbx))
>>   20: 488b5230   (mov rdx (mem64+ rdx #x30))
>>   24: 488b4208   (mov rax (mem64+ rdx #x8))
>>   28: 488983f8ff (mov (mem64+ rbx #x-8) rax)
>>   2f: 48b8a80e484c   (mov rax #x4c480ea8)
>>   39: 488b00 (mov rax (mem64+ rax))
>>   3c: 488983f0ff (mov (mem64+ rbx #x-10) rax)
>>   43: 4881c3f0ff (add rbx #xfff0)
>>   4a: 488b4308   (mov rax (mem64+ rbx #x8))
>>   4e: f6c001 (test al #x1)
>>   51: 0f850f00   (jnz (+ rip #xf))
>>   57: 66833831   (cmp (mem16+ rax) #x31)
>>   5b: 0f850500   (jnz (+ rip #x5))
>>   61: e81e771fb4 (call (+ rip #x-4be088e2))
>>   66: e8bb751fb4 (call (+ rip #x-4be08a45))
>>   6b: 488b4320   (mov rax (mem64+ rbx #x20))
>>   6f: 4883c310   (add rbx #x10)
>>   73: f6c001 (test al #x1)
>>   76: 0f851400   (jnz (+ rip #x14))
>>   7c: ba60fba070 (mov edx #x70a0fb60)
>>   81: b9ff01 (mov ecx #x1ff)
>>   86: e86e001fb4 (call (+ rip #x-4be0ff92))
>>   8b: e90700 (jmp (+ rip #x7))
>>   90: 4881e0ff01 (and rax #x1ff)
>>   97: 4c8b75c8   (mov r14 (mem64+ rbp #x-38))
>>   9b: 4883c428   (add rsp #x28)
>>   9f: 5f (pop rdi)
>>   a0: 5e (pop rsi)
>>   a1: 5b (pop rbx)
>>   a2: 5d (pop rbp)
>>   a3: c3 (ret)
>>
>> (define (unsafe-lsb x)
>>   (unsafe-fxand x #xff))
>>
>> (disassemble unsafe-lsb)
>>
>>0: 488983f8ff (mov (mem64+ rbx #x-8) rax)
>>7: 4881c3f8ff (add rbx #xfff8)
>>e: 488b4308   

Re: [racket-users] C level bit manipulation - Racket Manifesto

2018-08-11 Thread Sam Tobin-Hochstadt
There are basically two differences between the `unsafe-lsb` function
in Racket and the C one:
 - the Racket calling convention vs the C calling convention
 - the instruction used to perform the LSB calculation

For a variety of reasons Racket's function calling convention is more
heavyweight than C's, but if that code is inlined into some larger
function that will go away (as it would in C). The simpler instruction
used by the C compiler is because the C compiler recognizes that
pattern of bitwise and, whereas the Racket JIT does the obvious `and`.
That could of course be fixed in the JIT, although it's not clear how
much of a win it is.

More broadly, whether Racket supports "C-level" programming depends on
what you mean. If it means "can I use the same APIs and access the
same bits I would in C", then you certainly can, although often you
need to use the FFI to do so. That's what the Racket Manifesto means.
If it means "can I generate the same assembly instructions or get the
same maximum performance from pure Racket code as from C code", then
it isn't true, and you'll need to use some other tools, such as
generating code yourself (see https://github.com/rjnw/sham for an
example).

Sam

On Sat, Aug 11, 2018 at 4:15 AM, 'Paulo Matos' via Racket Users
 wrote:
> Hi,
>
> In http://felleisen.org/matthias/manifesto/, you can read:
> "In support, Racket offers protection mechanisms to implement a full
> language spectrum, from C-level bit manipulation to soundly typed
> extensions."
>
> What are we talking about here when we mention C-level bit manipulation? Is
> this referring to the ffi or some other Racket feature that allows me to
> generate unsafe bit manipulation instructions?
>
> In C, for a bitwise_and of an integer x and 0xff, I get:
> https://godbolt.org/g/gy3ZN9
> bitwise_and:
>   movzx eax, dil
>   ret
>
> In Racket, I tried:
> #lang racket
>
> (require disassemble
>  racket/unsafe/ops)
>
> (define (lsb x)
>   (bitwise-and x #xff))
>
> (disassemble lsb)
>
>0: 488b4808   (mov rcx (mem64+ rax #x8))
>4: 48898bf8ff (mov (mem64+ rbx #x-8) rcx)
>b: 488b4810   (mov rcx (mem64+ rax #x10))
>f: 48898bf0ff (mov (mem64+ rbx #x-10) rcx)
>   16: 4881c3f0ff (add rbx #xfff0)
>   1d: 488b13 (mov rdx (mem64+ rbx))
>   20: 488b5230   (mov rdx (mem64+ rdx #x30))
>   24: 488b4208   (mov rax (mem64+ rdx #x8))
>   28: 488983f8ff (mov (mem64+ rbx #x-8) rax)
>   2f: 48b8a80e484c   (mov rax #x4c480ea8)
>   39: 488b00 (mov rax (mem64+ rax))
>   3c: 488983f0ff (mov (mem64+ rbx #x-10) rax)
>   43: 4881c3f0ff (add rbx #xfff0)
>   4a: 488b4308   (mov rax (mem64+ rbx #x8))
>   4e: f6c001 (test al #x1)
>   51: 0f850f00   (jnz (+ rip #xf))
>   57: 66833831   (cmp (mem16+ rax) #x31)
>   5b: 0f850500   (jnz (+ rip #x5))
>   61: e81e771fb4 (call (+ rip #x-4be088e2))
>   66: e8bb751fb4 (call (+ rip #x-4be08a45))
>   6b: 488b4320   (mov rax (mem64+ rbx #x20))
>   6f: 4883c310   (add rbx #x10)
>   73: f6c001 (test al #x1)
>   76: 0f851400   (jnz (+ rip #x14))
>   7c: ba60fba070 (mov edx #x70a0fb60)
>   81: b9ff01 (mov ecx #x1ff)
>   86: e86e001fb4 (call (+ rip #x-4be0ff92))
>   8b: e90700 (jmp (+ rip #x7))
>   90: 4881e0ff01 (and rax #x1ff)
>   97: 4c8b75c8   (mov r14 (mem64+ rbp #x-38))
>   9b: 4883c428   (add rsp #x28)
>   9f: 5f (pop rdi)
>   a0: 5e (pop rsi)
>   a1: 5b (pop rbx)
>   a2: 5d (pop rbp)
>   a3: c3 (ret)
>
> (define (unsafe-lsb x)
>   (unsafe-fxand x #xff))
>
> (disassemble unsafe-lsb)
>
>0: 488983f8ff (mov (mem64+ rbx #x-8) rax)
>7: 4881c3f8ff (add rbx #xfff8)
>e: 488b4308   (mov rax (mem64+ rbx #x8))
>   12: 4881e0ff01 (and rax #x1ff)
>   19: 4c8b75c8   (mov r14 (mem64+ rbp #x-38))
>   1d: 4883c428   (add rsp #x28)
>   21: 5f (pop rdi)
>   22: 5e (pop rsi)
>   23: 5b (pop rbx)
>   24: 5d 

[racket-users] C level bit manipulation - Racket Manifesto

2018-08-11 Thread 'Paulo Matos' via Racket Users

Hi,

In http://felleisen.org/matthias/manifesto/, you can read:
"In support, Racket offers protection mechanisms to implement a full 
language spectrum, from C-level bit manipulation to soundly typed 
extensions."


What are we talking about here when we mention C-level bit manipulation? 
Is this referring to the ffi or some other Racket feature that allows me 
to generate unsafe bit manipulation instructions?


In C, for a bitwise_and of an integer x and 0xff, I get: 
https://godbolt.org/g/gy3ZN9

bitwise_and:
  movzx eax, dil
  ret

In Racket, I tried:
#lang racket

(require disassemble
 racket/unsafe/ops)

(define (lsb x)
  (bitwise-and x #xff))

(disassemble lsb)

   0: 488b4808   (mov rcx (mem64+ rax #x8))
   4: 48898bf8ff (mov (mem64+ rbx #x-8) rcx)
   b: 488b4810   (mov rcx (mem64+ rax #x10))
   f: 48898bf0ff (mov (mem64+ rbx #x-10) rcx)
  16: 4881c3f0ff (add rbx #xfff0)
  1d: 488b13 (mov rdx (mem64+ rbx))
  20: 488b5230   (mov rdx (mem64+ rdx #x30))
  24: 488b4208   (mov rax (mem64+ rdx #x8))
  28: 488983f8ff (mov (mem64+ rbx #x-8) rax)
  2f: 48b8a80e484c   (mov rax #x4c480ea8)
  39: 488b00 (mov rax (mem64+ rax))
  3c: 488983f0ff (mov (mem64+ rbx #x-10) rax)
  43: 4881c3f0ff (add rbx #xfff0)
  4a: 488b4308   (mov rax (mem64+ rbx #x8))
  4e: f6c001 (test al #x1)
  51: 0f850f00   (jnz (+ rip #xf))
  57: 66833831   (cmp (mem16+ rax) #x31)
  5b: 0f850500   (jnz (+ rip #x5))
  61: e81e771fb4 (call (+ rip #x-4be088e2))
  66: e8bb751fb4 (call (+ rip #x-4be08a45))
  6b: 488b4320   (mov rax (mem64+ rbx #x20))
  6f: 4883c310   (add rbx #x10)
  73: f6c001 (test al #x1)
  76: 0f851400   (jnz (+ rip #x14))
  7c: ba60fba070 (mov edx #x70a0fb60)
  81: b9ff01 (mov ecx #x1ff)
  86: e86e001fb4 (call (+ rip #x-4be0ff92))
  8b: e90700 (jmp (+ rip #x7))
  90: 4881e0ff01 (and rax #x1ff)
  97: 4c8b75c8   (mov r14 (mem64+ rbp #x-38))
  9b: 4883c428   (add rsp #x28)
  9f: 5f (pop rdi)
  a0: 5e (pop rsi)
  a1: 5b (pop rbx)
  a2: 5d (pop rbp)
  a3: c3 (ret)

(define (unsafe-lsb x)
  (unsafe-fxand x #xff))

(disassemble unsafe-lsb)

   0: 488983f8ff (mov (mem64+ rbx #x-8) rax)
   7: 4881c3f8ff (add rbx #xfff8)
   e: 488b4308   (mov rax (mem64+ rbx #x8))
  12: 4881e0ff01 (and rax #x1ff)
  19: 4c8b75c8   (mov r14 (mem64+ rbp #x-38))
  1d: 4883c428   (add rsp #x28)
  21: 5f (pop rdi)
  22: 5e (pop rsi)
  23: 5b (pop rbx)
  24: 5d (pop rbp)
  25: c3 (ret)

This returns two assembly listings and as expected the unsafe-lsb is 
shorter than the one for lsb but not even close to the one you'd get in 
C. Is there something else in Racket that I might be missing that it 
gives me access to the low level C bit manip constructs besides ffi?


Kind regards,

--
Paulo Matos

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.