[Openmcl-devel] CCL on a Raspberry pi
Gary Byers
gb at clozure.com
Fri Jul 27 08:03:42 PDT 2012
On Sat, 21 Jul 2012, Gary Byers wrote:
> Late-breaking news:
>
That was -so- r14523 ... As of r14525 in the trunk, CCL should run under
Linux on ARMv6 machines (like the Raspberry Pi) as well as ARMv7-a. Thanks
to Ron Garrett for letting me use his Raspberry Pi for testing.)
- the other day, I said that I was leaning towards spinning off a separate
ARMv6-specific version. Sanity prevailed, and it seemed to make more sense
to have a single ARM version that ran on ARMv6 and ARMv7(a) machines and
to simply refrain from using ARMv7-specific instructions in most cases
(and to only use them conditionally in other cases.)
- the FASL file version changed (for ARM), as did the version number which
controls kernel/image compatibility. If you're updating an existing svn
tree, be sure that you pick up the new binaries (by using the "tf" conflict
resolution option if possible, or by doing "svn revert" otherwise.) Failure
to observe this may cause bootstrapping problems and complaining about that
will result in a US$4 fine.
- the lisp kernel was built on a Debian "squeeze" system and my model of things
is that it should run on ARMv6 systems as well as ARMv7 (but see below about
"armhf" issues.) For a number of reasons, the ARM toolchain world is and has
been a moving target and I can't be sure that something I build here will run
on all distributions that it "should" run on; if it doesn't run on yours, the
first thing to try is to rebuild the kernel locally.
- traditionally, ARM Linux systems have used a C ABI in which floating-point
arguments were passed in general-purpose registers or stack locations and
floating-point results were returned in general-purpose registers;
this convention allowed the same C code to "work" regardless of whether
or not floating-point hardware was present. This was known as the "soft
float ABI".
Linux distributions are moving toward (or have moved to) a newer ABI in which
the presence of an FPU is assumed and in which many FP arguments and
FP results are passed/returned in floating-point registers; since transferring
FP values to/from the stack and GPRs can be expensive, this ABI often yields
substantial performance gains for floating-point-intensive C code. This is
known as the "hard float ABI" and the term "armhf" is often used to indicate
support for that ABI.
The two ABI's can't be mixed: object and dynamic files compiled for one
ABI can't be linked with files compiled for the other. Some distributions
are still exclusively soft-float, some are exclusively hard-float, and
some (Ubuntu 12.04, for example) can be made to support both ABIs (and provide
two incompatible sets of system libraries.)
From CCL's point of view, this (only) affects how foreign function calls and
callbacks that have floating-point arguments and/or results are implemented.
Since it's likely that both ABIs will coexist (in some sense or another) for
at least the next few years, we generally want to support both ABIs
as transparently as possible. This is partially implemented in the trunk.
The CCL kernel can be built as either a soft- or hard-float application (despite
the fact that the kernel itself barely does any floating-point arithmetic).
The file ccl/lisp-kernel/linuxarm/float_abi.mk is included in the linuxarm
kernel Makefile. It defines FLOAT_ABI to be one of "softfp" or "hard", with
the other value commented out; as distributed, the file defines FLOAT_ABI
to be "softfp". If you want to build a "hard-float" version of the CCL
kernel, it's necessary to change the defined value of FLOAT_ABI in this
file and then do:
$ cd lisp-kernel/linuxarm
$ make clean # delete existing .o files
$ make
and that should produce a ccl/armcl executable that uses (and can use libraries
that use) the hard-float ABI.
How the CCL kernel is built affects the calling convention that libraries that
the CCL kernel are linked against use. Lisp code is only affected by the
float-abi change when calling or being called by C code and when FP arguments/
results are involved. There isn't much such code in CCL itself (things like SIN
may be partially implemented by calling #_sin or #_sinf and that's true for
10-20 other math functions) and even for applications that make heavy use of
FP-intensive foreign code (OpenGL might be one case), the actual FFI code is likely
to be a very small part of the entire heap image; it wouldn't make sense to have
separate hard- and soft-float CCL images; the plan is to instead try to support
both ABIs (at least until the soft-float ABI fades away.)
For calls to foreign functions where float args/results are involved, we can
basically compile both the soft- and hard-float case and select one of them
at runtime. (#_sin x) becomes something like:
(external-call "sin" :double-float x :double-float)
and that becomes something like:
(if *hard-float-abi-in-use* ; based on how the lisp kernel was built
(external-call-using-hard-float-abi "sin" ...)
(external-call-using-soft-float-abi "sin" ...))
That's implemented in the trunk and it seems to work well. (I think that
there are still some cases where calls involving more than 16 single-floats
or more than 8 double-floats aren't handled correctly, but otherwise ...)
That's the good news. The bad news is that something analogous has to
happen for callbacks involving floats, and the necessary changes haven't
been made yet. (So callbacks involving floats will only behave correctly
when the soft-float ABI is in effect.)
None of the above (the hard vs soft-float ABI isssues) have anything to do
with ARMv7 vs ARMv6. Both architectures can support either ABI.
More information about the Openmcl-devel
mailing list