Hacker News new | ask | show | jobs
by srean 5274 days ago
Are you sure that BLAS uses different matrix multiplication algorithm ?

I havent looked at the actual code in a while, but from what I have seen they use the standard vanilla matrix multiplication algorithm whose complexity is no less than O(N^3) (for square matrices).

They achieve the speed by exploiting the deep cache structure of modern machines. Essentialy by blocking (sometimes unrolling) loops and consuming data in a cache aware fashion. Given the latency in accessing the data directly from memory, getting the data off the cache can easily speed things up by 10s if not 100s of folds.

In otherwords, its the same algorithm just implemented more efficiently.

On the other hand is the interesting question if linear algebra can be done fast in a lisp without calling BLAS. I do not have the reference on the top of my head but there were a few papers on ACM where it was shown that lisp can indeed rival fortran speed in linear algebraic computation. I will try and dig it up later. In anycase I suspect that stalin will do a decent job optimizing a matrix multiplication routine written in lisp. I suspect that a part of the slowdown in clojure is also because it runs on jvm whose safety guarantees (bounds checking and no reordering of instructions) can come with a speed hit.

EDIT: here it is http://www.cs.berkeley.edu/~fateman/papers/lispfloat.ps

From the abstract:

  Lisp, one of the oldest higher-level programming languages
  has rarely been used for fast numerical (floating-point)
  computation. We explore the benefits of Common Lisp, an
  emerging new language standard with some excellent
  implementations, for numerical computation.
  We compare it to Fortran in terms of the speed of
  generated code, as well as the structure and convenience
  of the language. There are a surprising number of
  advantages to Lisp, especially in cases where a mixture
  of symbolic and numeric processing is needed
And the conclusion:

  In this article we have asserted, and shown through a
  number of examples, that numerical computing in Lisp need
  not be slow, and that many features of Common
  Lisp are useful in the context of numerical computing. We
  have demonstrated that the speed of compiled Common Lisp
  code, though today somewhat slower than that of the best
  compiled Fortran, could probably be as efficient, and in
  some ways superior. We have suggested ways in which the
  speed of this code might be further improved.
Should be read with http://dl.acm.org/citation.cfm?id=235815.235824 (this is probably pay-walled).
1 comments

BLAS is an API. Just because the reference implementation does things in a particular way does not necessarily mean that that your vendor implementation cannot do things differently (e.g. Apple's numerics team has spent a considerable amount of time tuning BLAS for Apple hardware).

For the particular problem discussed in the original article, there are at least two ways the multiplication A'A could potentially be made faster:

1) The blas _GEMM matrix multiplication routine lets you specify whether input matrix arguments are supposed to be transposed. This gets rid of the explicit transposition, AND in this problem, it lets you compute each element as the dot product of two unit stride vectors, instead of a dot product of an unit stride vector with a nonunit stride vector. For SSE, this makes a huge difference.

2) For the particular case A'A, there is the even more specialized _SYRK routine, which at the very least should be cache friendlier than a naive _GEMM (_GEMM could also figure out that it can use _SYRK for this problem, and presumably it does so in some implementation)

I dont think I claimed that a vendor "cannot do things differently". Not sure where the downvotes came from, so just clarifying.

I would also hazard a guess that the tuning that you mention does not involve a change in the algorithm but are essentially reordering the steps of the algorithm to obtain better caching. I was responding to the parent post which conjectured that BLAS implementations use different algorithms. If you look at your two suggestions, none of them actually change the complexity class of the number of floating operations, but wall clock time oh absolutely.

Although there are matrix multiplication algorithms that have a complexity less than O(N^3) the constants for these are so large enough that the sizes of matrices for which there will be any appreciable benefit are extremely rare to come by.

Apple did not spent a considerable amount of time tunning BLAS - they just took Atlas, an widely used open source implementation of blas/lapack (and took care of making sure it does not look like ATLAS at first glance, although a simple look at nm will show it is atlas all the way down).
The OS X BLAS was once ATLAS all the way down (and I see no reason to believe that any effort was made to hide that fact), but that's no longer true. A glance at nm on Lion shows that there's some ATLAS in there, but quite a lot of not-ATLAS too.
It is mentioned nowhere in accelerate framework that it uses atlas, and they removed functions like ATL_buildinfo. I doubt it has changed much in the last 5 years as well, and I am not sure what makes you think there is ( significant) non-atlas code in there ? Besides symbols starting with ATL, I see mostly the BLAS/LAPACK API, although I did not try to check very carefully.
Besides the ATL-prefixed symbols, there are are numerous APL-prefixed symbols, as well as many _block_ symbols which indicate extensive use of GCD in the level 3 routines (and which ATLAS doesn't use).
The gemm -> syrk optimization is very common (I would expect most tuned BLAS libraries to take advantage of it -- all that I have inspected do so).