What are the things that optimize speed declaration do in CL? - functional-programming

What are some of the optimization steps that this command does
`(optimize speed (safety 0))`
Can I handcode some of these techniques in my Lisp/Scheme program?

What these things do in CL depends on the implementation. What usually happens is: there's a bunch of optimizations and other code transformations that can be applied on your code with various tradeoffs, and these declarations are used as a higher level specification that is translated to these individual transformations. Most implementations will also let you control the individual settings, but that won't be portable.
In Scheme there is no such standard facility, even though some Schemes use a similar approach. The thing is that Scheme in general (ie, in the standard) avoids such "real world" issues. It is possible to use some optimization techniques here and there, but that depends on the implementation. For example, in PLT the first thing you should do is make sure your code is defined in a module -- this ensures that the compiler gets to do a bunch of optimizations like inlining and unfolding loops.

I don't know, but I think the SBCL internals wiki might have some starting points if you want to explore.

Higher speed settings will cause the compiler to work harder on constant folding, compile-time type-inference (hence eliminating runtime dynamic dispatches for generic operations) and other code analyses/transformations; lower safety will skip runtime type checks, array bound checks, etc. For more details, see
Advanced Compiler Use and Efficiency Hints chapter of the CMUCL User's Manual, which applies to both CMUCL and SBCL(more or less).

Related

OpenCL: better to use macros or functions?

In OpenCL, which is C-99, we have two options for creating something function-like:
macros
functions
[edit: well, or use a templating language, new option 3 :-) ]
I heard somewhere (can't find any official reference to this anywhere, just saw it in a comment somewhere on stackoverflow, once), that functions are almost always inlined in practice, and that therefore using functions is ok performance-wise?
But macros are basically guaranteed to be inlined, by the nature of macros. But susceptible to bugs, eg if dont add parentheses around everything, and not typesafe.
In practice, what works well? What is most standard? What is likely to be most portable?
I suppose my requirements are some combination of:
as fast as possible
as little register pressure as possible
when used with compile-time constants, should ideally be guaranteed to be optimized-away to another constant
easy to maintain...
standard, not too weird, since I'm looking at using this for an opensource project, that I hope other people will contribute to
But macros are basically guaranteed to be inlined, by the nature of macros.
On GPU at least, the OpenCL compilers aggressively inlines pretty much everything, with the exception of recursive functions (OpenCL 2.0). This is both for hardware constraints and performance reasons.
While this is indeed implementation dependent, I have yet to see a GPU binary that is not aggressively inlined. I do not work much with CPU OpenCL but I believe the optimizer strategy may be similar, although the hardware constraints are not the same.
But as far as the standard is concerned, there are no guarantees.
Let's go through your requirements:
as fast as possible
as little register pressure as possible
when used with compile-time constants, should ideally be guaranteed to be optimized-away to another constant
Inline functions are as fast as macros, do not use more registers, and will be optimized away when possible.
easy to maintain...
Functions are much easier to maintain that macros. They are type safe, they can be refactored easily, etc, the list goes on forever.
standard, not too weird, since I'm looking at using this for an opensource project, that I hope other people will contribute to
I believe that is very subjective. I personally hate macros with a passion and avoid them like the plague. But I know some very successful projects that use them extensively (for example Boost.Compute). It's up to you.

What are the main differences between CLISP, ECL, and SBCL?

I want to do some simulations with ACT-R and I will need a Common Lisp implementation. I have three Common Lisp implementations available: (1) CLISP [1], (2) ECL [1], and (3) SBCL [1]. As you might have gathered from the links I have read a bit about all three of them on Wikipedia. But I would like the opinion of some experienced users. More specifically I would like to know:
(i) What are the main differences between the three implementations (e.g.: What are they best at? Is any of them used only for specific purposes and might therefore not be suited for specific tasks?)?
(ii) Is there an obvious choice either based on the fact that I will be using ACT-R or based on general reasons?
As this could be interpreted as a subjective question
I checked What topics can I ask about here and What types of questions should I avoid asking? and if I read correctly it should not qualify as forbidden fruit.
I wrote a moderately-sized application and ran it in SBCL, CCL, ECL, CLISP, ABCL, and LispWorks. For my application, SBCL is far and away the fastest, and it's got a pretty good debugger. It's a bit strict about some warnings--you may end up coding in a slightly more regimented way, or turn off one or more warnings.
I agree with Sylwester: If possible, write to the standard, and then you can run your code in any implementation. You'll figure out through testing which is best for your project.
Since SBCL compiles so agressively, once in a while the stacktrace in the debugger is less informative than I'd like. This can probably be controlled with parameters, but I just rerun the same code in one of the other implementations. ABCL has an informative stacktrace, for example, as I recall. (It's also very slow, but if you want real Common Lisp and Java interoperability, it's the only option.)
One of the nice things about Common Lisp is how many high-quality implementations there are, most of them free.
For informal use--e.g. to learn Common Lisp, CCL or CLISP may be a better choice than SBCL.
I have never tried compiling to C using ECL. It's possible that it would beat SBCL on speed for some applications. I have no idea.
CLISP and LispWorks will not handle arbitrarily long argument lists (unless that's been fixed in the last couple of years, but I doubt it). This turned out to be a problem with my application, but would not be a problem for most code.
Doesn't ACT-R come out of Carnegie Mellon? What do its authors use? My guess would be CMUCL or SBCL, which is derived from CMUCL. (I only tried CMUCL briefly. Its interpreter is very slow, but I assume that compiled code is very fast. I think that most people choose SBCL over CMUCL, however.)
(It's possible that this question belongs on Programmers.SE.)
In general, SBCL is the default choice among open-source Lisps. It is solid, well-supported, produces fast code, and provides many goodies beyond what the standard mandates (concurrency primitives, profiling, etc.) Another implementation with similar properties is CCL.
CLISP is more suitable if you're not an engineer, or you want to quickly show Lisp to someone non-engineer. It's a pretty basic implementation, but quick to get running and user-friendly. A Lisp-calculator :)
ECL's major selling point is that it's embeddable, i.e. it is rather easy to make it work inside some C application, like a web-server etc. It's a good choice for geeks, who want to explore solutions on the boundary of Lisp and the outside world. If you're not intersted in such use case I wouldn't recommend you to try it, especially since it is not actively supported, at the moment.
Their names, their bugs and their non standard additions (using them will lock you in)
I use CLISP as REPL and testing during dev and usually SBCL for production. ECL i've never used.
I recommend you test your code with more than one implementation.

Program extraction using native integers/words (not bignums) from Isabelle theory

This question comes in a context where Isabelle is used with formal software development in mind more than with pure maths theorization in mind (and from a standalone developer's context).
Seems at best, SML programs generated from an Isabelle theory, use SML's IntInf.int, not the native integer type, which is Int.int; even if Code_Target_Int, Code_Binary_Nat or Code_Target_Nat is used. Investigation of these theories sources seems to confirm it's all it can do. Native platform integers may be required for multiple reasons, including efficiency and the case the SML imperative program is to be optionally translated into an imperative language subset (ex. C or Ada), which is relevant when the theory relies on the Imperative_HOL theory. The codegen.pdf document which comes with the Isabelle distribution, did not help with it, except in suggesting the first of the options below.
Options may be:
Not using Isabelle's int and nat and re‑create a new numeric type from scratch, then use the code_printing commands (with its type_constructor and constant) to give it the native platform representation and operations (implies inclusion of range limitations in some way in the theory) : must be tedious, although unlikely error‑prone I hope, due to the formal environment. Note this does seems feasible with Isabelle's own int and nat… it makes code generation fails, and nothing tells which constants are missing in the code_printing command.
If the SML program is to be compiled directly (ex. with MLTon), tweak the SML environment with a replacement IntInf structure : may be unsafe or not feasible, and still requires to embed the range limitations in the theory, so the previous options may finally be better than this one.
Touch the generated program to change IntInf into Int : easy, but it is safe? (at least, IntInf implements the same signature as Int do, so may be it's safe). As above, requires to specifies bounds in the theory in some way, it's OK with this.
Dive into Isabelle internals : surely unreasonable, even worse than the second option.
There exist a Word theory, but according to some readings, it's seems not suited for that purpose.
Are they other known options not listed here? Are they comments on the listed options?
If there is no ready‑to‑cook solutions (I feel there is no at the time), what hints or tracks would be best known? (ex. links to documents, mentions of concepts).
Update
Points #2 and #3 of the list, may be OK (if it really is) only if there is a single integer type. If the program use more than only one, it's not applicable.
Directly generating native words from Isabelle int would be unsound, because your formalisation would not take overflow into account where it exists in reality.
It looks like the AFP entry Native_Word does what you want, though:
http://afp.sourceforge.net/entries/Native_Word.shtml

How to set a pragma to constrain Ada's functionality to Pascal

I intend to use Ada for some programs. I remember reading somewhere that with pragmas you can set compiler instructions to optimize your program. More specifically, I remember reading that if you need only a limited subset of Ada functionality (basically corresponding to Pascal, but with Ada's strong typing), you can use pragmas to specify a sort of 'Pascal-like mode' (I use this term for lack of a better expression). My aim is disabling those runtime checks that I don't need (since I only need basic functionality), thus reducing the size of the executable and enhancing the performance.
My question is: how do I set such a pragma? What parameters/options should I specify?
Thank you
This perhaps comes from a misunderstanding.
Ada is not a superset of Pascal. It is a fair bit more accurate to view them as sibling languages of the parent language Algol 60. Pascal was orginally developed by Niklaus Wirth to be a simplified version of Algol 60. The Algol folks instead went the other way with what became Algol 68.
Ada was instead a new language designed from scratch that borrowed from Algol 60's syntax (in much the way that Java borrows from C's syntax). It is however much more complex (some would use the word "functional") than even Algol 68.
So asking for a "Pascal flag" in your Ada compiler is much like asking for a "C++ flag" in your Java compiler.
If you are just looking for a free Pascal compiler, you might instead look at using Free Pascal or GNU Pascal.
If you are just looking to decrease the overhead of unused runtime facilities, you should look into Annex H, which lets you to use pragma Restrictions() to selectively disallow access to parts of the Ada runtime. That allows you to get rid of things like floating-point, dynamic allocation, dynamic dispatch, tasking, exceptions/runtime constraint checks, etc.
I'm sorry, but this is a Bad Idea. If you want to avoid any possible overhead from tasking constructs, then don't use tasking! People often want to suppress constraint checking (which you can do in GNAT by compiling with -p) but - in my experience - you rarely get more than a small improvement.
Ada now has pragma Restrictions, which prevents you using certain features; you can see GNAT's here. The aims are to support production of high-integrity software, portable software, or efficient tasking runtimes.
That {'Pascal-like mode'} sounds like a implementation-specific pragma, unless I'm misunderstanding you.
Though there are the 'optimize[time or space] andrestriction` pragmas that might impact your final size.

How do I use Declarations (type, inline, optimize) in Scheme?

How do I declare the types of the parameters in order to circumvent type checking?
How do I optimize the speed to tell the compiler to run the function as fast as possible like (optimize speed (safety 0))?
How do I make an inline function in Scheme?
How do I use an unboxed representation of a data object?
And finally are any of these important or necessary? Can I depend on my compiler to make these optimizations?
thanks,
kunjaan.
You can't do any of these in any portable way.
You can get a "sort of" inlining using macros, but it's almost always to try to do that. People who write Scheme (or any other language) compilers are usually much better than you in deciding when it is best to inline a function.
You can't make values unboxed; some Scheme compilers will do that as an optimization, but not in any way that is visible (because it is an optimization -- so it should preserve the semantics).
As for your last question, an answer is very subjective. Some people cannot sleep at night without knowing exactly how many CPU cycles some function uses. Some people don't care and are fine with trusting the compiler to optimize things reasonably well. At least at the stages where you're more of a student of the language and less of an implementor, it is better to stick to the latter group.
If you want to help out the compiler, consider reducing top level definitions where possible.
If the compiler sees a function at top-level, it's very hard for it to guess how that function might be used or modified by the program.
If a function is defined within the scope of a function that uses it, the compiler's job becomes much simpler.
There is a section about this in the Chez Scheme manual:
http://www.scheme.com/csug7/use.html#./use:h4
Apparently Chez is one of the fastest Scheme implementations there is. If it needs this sort of "guidance" to make good optimizations, I suspect other implementations can't live without it either (or they just ignore it all together).

Resources