* questions about costs of nativeint vs int @ 2001-01-10 18:25 Norman Ramsey 2001-01-11 9:17 ` Cost of polymorphic variants over normal ones Sven LUTHER 2001-01-11 18:34 ` questions about costs of nativeint vs int Xavier Leroy 0 siblings, 2 replies; 8+ messages in thread From: Norman Ramsey @ 2001-01-10 18:25 UTC (permalink / raw) To: caml-list We're designing interfaces for tools that will sometimes have to manipulate 32-bit integers, but will often be able to make do with the limited precision provided by the int type. I would love to get some information about the relative cost of int vs nativeint in both parameter passing and datatype representation. For example, what are the relative costs (e.g., memory requirements) of these two definitions? type loc = Cell of char * int * width | Slice of ... type loc' = Cell of char * nativeint * width | Slice of ... As another example, what are the costs of calling these functions: type t val add : rd:int -> rs1:int -> rs2:int -> t val add' : rd:nativeint -> rs1:nativeint -> rs2:nativeint -> t To extend the question, what happens if I use int32 or int64 in place of nativeint? Finally, a procedural question: should I be posting these sorts of questions to comp.lang.ml instead of sending them to caml-list@inria.fr? Thanks in advance for any help! Norman ^ permalink raw reply [flat|nested] 8+ messages in thread
* Cost of polymorphic variants over normal ones. 2001-01-10 18:25 questions about costs of nativeint vs int Norman Ramsey @ 2001-01-11 9:17 ` Sven LUTHER 2001-01-11 10:40 ` Alain Frisch 2001-01-11 14:50 ` Jacques Garrigue 2001-01-11 18:34 ` questions about costs of nativeint vs int Xavier Leroy 1 sibling, 2 replies; 8+ messages in thread From: Sven LUTHER @ 2001-01-11 9:17 UTC (permalink / raw) To: caml-list On Wed, Jan 10, 2001 at 01:25:27PM -0500, Norman Ramsey wrote: > We're designing interfaces for tools that will sometimes have to > manipulate 32-bit integers, but will often be able to make do with the > limited precision provided by the int type. I would love to get some > information about the relative cost of int vs nativeint in both > parameter passing and datatype representation. > A (somewhat) related question would be, what is the cost of polymorphic variants compared to noarmal ones ? The normal variants are coded as integers, and using them is fast, while polymorphic variants use some kind of hash functionn, but very simple. If i use a datatype that i will be pattern matching very often and i want it to be quick, how much is the overhead of using polymorphic patterns over noraml ones ? Or did i misunderstand the way it works ? Friendly, Sven Luther ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Cost of polymorphic variants over normal ones. 2001-01-11 9:17 ` Cost of polymorphic variants over normal ones Sven LUTHER @ 2001-01-11 10:40 ` Alain Frisch 2001-01-11 10:44 ` Sven LUTHER 2001-01-11 14:50 ` Jacques Garrigue 1 sibling, 1 reply; 8+ messages in thread From: Alain Frisch @ 2001-01-11 10:40 UTC (permalink / raw) To: Sven LUTHER; +Cc: caml-list On Thu, 11 Jan 2001, Sven LUTHER wrote: > A (somewhat) related question would be, what is the cost of polymorphic > variants compared to noarmal ones ? > > The normal variants are coded as integers, and using them is fast, while > polymorphic variants use some kind of hash functionn, but very simple. AFAIK, the hashing is done only during the compilation (or explicitly by external C functions). For instance (output of ocaml -dinstr): # function `ABC -> 10 | `DEF -> 20;; closure L1, 0 return 1 L1: const 3247170 push acc 1 eqint branchifnot L2 const 10 return 1 L2: const 20 return 1 > If i use a datatype that i will be pattern matching very often and i want it > to be quick, how much is the overhead of using polymorphic patterns over > noraml ones ? There may be a small overhead because the variants tags are large, so the compiler can't use the "switch" instruction of the abstract machine. Compare with (type t = ABC | DEF): # function ABC -> 10 | DEF -> 20;; closure L1, 0 return 1 L1: acc 0 switch 3 2/ L3: const 10 return 1 L2: const 20 return 1 For the native code, the difference is less visible (ocamlopt -S): .L102: cmpl $6494341, %eax jne .L101 movl $21, %eax ret .L101: movl $41, %eax ret and: .L105: sarl $1, %eax testl %eax, %eax je .L104 movl $41, %eax ret .L104: movl $21, %eax ret (I think the new compilation scheme for pattern matching doesn't affect these cases). For more complex case, small value for tags allow optimizations. (see for instance the assembler code produced for: function `ABC -> 10 | `DEF -> 20 | `GHI -> 30;; type t = ABC | DEF | GHI;; function ABC -> 10 | DEF -> 20 | GHI -> 30;; ) -- Alain Frisch ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Cost of polymorphic variants over normal ones. 2001-01-11 10:40 ` Alain Frisch @ 2001-01-11 10:44 ` Sven LUTHER 0 siblings, 0 replies; 8+ messages in thread From: Sven LUTHER @ 2001-01-11 10:44 UTC (permalink / raw) To: Alain Frisch; +Cc: Sven LUTHER, caml-list On Thu, Jan 11, 2001 at 11:40:05AM +0100, Alain Frisch wrote: > On Thu, 11 Jan 2001, Sven LUTHER wrote: > > > A (somewhat) related question would be, what is the cost of polymorphic > > variants compared to noarmal ones ? > > > > The normal variants are coded as integers, and using them is fast, while > > polymorphic variants use some kind of hash functionn, but very simple. > > AFAIK, the hashing is done only during the compilation (or explicitly > by external C functions). For instance (output of ocaml -dinstr): Thanks for this info, i almost guessed that such was the cas,e but was not sure, Friendly, Sven Luther ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Cost of polymorphic variants over normal ones. 2001-01-11 9:17 ` Cost of polymorphic variants over normal ones Sven LUTHER 2001-01-11 10:40 ` Alain Frisch @ 2001-01-11 14:50 ` Jacques Garrigue 2001-01-11 19:14 ` Markus Mottl 1 sibling, 1 reply; 8+ messages in thread From: Jacques Garrigue @ 2001-01-11 14:50 UTC (permalink / raw) To: luther; +Cc: caml-list From: Sven LUTHER <luther@dpt-info.u-strasbg.fr> > A (somewhat) related question would be, what is the cost of polymorphic > variants compared to noarmal ones ? > > The normal variants are coded as integers, and using them is fast, while > polymorphic variants use some kind of hash functionn, but very simple. They are also coded as integers. The hash function is only used at compile time. > If i use a datatype that i will be pattern matching very often and i want it > to be quick, how much is the overhead of using polymorphic patterns over > noraml ones ? The difference is that since the integers are the result of a hash function, you cannot use an indirect jump through a table, like with normal variants. So pattern matching is compiled as a binary tree of "if" statements. Same thing happens in C when you switch on scattered cases. I did benchmarks a long time ago, and the overhead was rather costly with the bytecode interpreter, which has a builtin table-switch operation. Something like 3 times slower for a 10 way match, which just corresponds to the depth of the decision tree. Yet this is logarithmic, so a 100-way match would still only be around 6 times slower. However I was surprised to see that with the native code compiler polymorphic variants appeared to be faster than normal ones. That seems to mean than on modern CPUs, an indirect jump is about 3 times more expansive than a conditional, and that polymorphic variants are only going to be slow on huge matches. But this was a single, very simple benchmark, so I'm not sure this behaviour is stable. So, I wouldn't suggest using polymorphic variants to encode instructions in a virtual machine (too many cases), but in almost any other cases the overhead should be neglectable anyway. Keeping typing straightforward is another problem. Jacques Garrigue ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Cost of polymorphic variants over normal ones. 2001-01-11 14:50 ` Jacques Garrigue @ 2001-01-11 19:14 ` Markus Mottl 0 siblings, 0 replies; 8+ messages in thread From: Markus Mottl @ 2001-01-11 19:14 UTC (permalink / raw) To: Jacques Garrigue; +Cc: luther, caml-list > However I was surprised to see that with the native code compiler > polymorphic variants appeared to be faster than normal ones. That > seems to mean than on modern CPUs, an indirect jump is about 3 times > more expansive than a conditional, and that polymorphic variants are > only going to be slow on huge matches. But this was a single, very > simple benchmark, so I'm not sure this behaviour is stable. This is also in accordance with a test that I did a few years ago (in C++): I wondered whether it is more efficient to use function pointers (jump tables) or case switches to choose the next code part to be executed. I was surprised to find out that such tables only started paying off at numbers of around 100 alternatives (I certainly did this test on Intel chips, but if I remember correctly, it is also true for Alphas). I guess this may have to do with pipelining and/or cache effects. Processor experts can probably tell us more... - Markus Mottl -- Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: questions about costs of nativeint vs int 2001-01-10 18:25 questions about costs of nativeint vs int Norman Ramsey 2001-01-11 9:17 ` Cost of polymorphic variants over normal ones Sven LUTHER @ 2001-01-11 18:34 ` Xavier Leroy 2001-01-11 22:17 ` Norman Ramsey 1 sibling, 1 reply; 8+ messages in thread From: Xavier Leroy @ 2001-01-11 18:34 UTC (permalink / raw) To: Norman Ramsey; +Cc: caml-list Dear Norman, > We're designing interfaces for tools that will sometimes have to > manipulate 32-bit integers, but will often be able to make do with the > limited precision provided by the int type. I would love to get some > information about the relative cost of int vs nativeint in both > parameter passing and datatype representation. Values of type "nativeint", "int32" and "int64" are boxed (heap-allocated and handled through a pointer), while values of type "int" are unboxed. So, in terms of space, we have: nativeint 1 word for the pointer + 2 words for the heap block int32 same int64 same on 64-bit machines, add 1 word for a 32-bitter int 1 word for the data In terms of speed, operations on boxed integers are more expensive due to the extra loads (on operands) and heap allocations (on results). ocamlopt can avoid loads and allocations that cancel each other in simple cases, but the fact remains that nativeint arithmetic is more expensive than int arithmetic. > For example, what are the relative costs (e.g., memory requirements) > of these two definitions? > > type loc = Cell of char * int * width > | Slice of ... > > type loc' = Cell of char * nativeint * width > | Slice of ... A "Cell" requires two more memory words in the latter case. > As another example, what are the costs of calling these functions: > > type t > val add : rd:int -> rs1:int -> rs2:int -> t > val add' : rd:nativeint -> rs1:nativeint -> rs2:nativeint -> t Assuming the nativeints are already available, the cost is exactly the same: a pointer is passed instead of an unboxed integer. However, computing the nativeint arguments in the first place can be more expensive if arithmetic operations are involved. > To extend the question, what happens if I use int32 or int64 in place > of nativeint? No major differences. On a 32-bit processor, int64 requires one more memory word than the other two. And of course 64-bit arithmetic is slower than 32-bit arithmetic on a 32-bit processor. Actually, "nativeint" is isomorphic to "int32" on a 32-bit platform and to "int64" on a 64-bit platform. The reason for having all three types is that some applications require 32-bit integers (no more, no less, regardless of the platform), some require 64-bit integers, and some just want to get at the natural word size for the architecture. > Finally, a procedural question: should I be posting these sorts of > questions to comp.lang.ml instead of sending them to > caml-list@inria.fr? For technical questions about the Caml implementation, I think you get a better chance of a reply here on caml-list. All the best, - Xavier ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: questions about costs of nativeint vs int 2001-01-11 18:34 ` questions about costs of nativeint vs int Xavier Leroy @ 2001-01-11 22:17 ` Norman Ramsey 0 siblings, 0 replies; 8+ messages in thread From: Norman Ramsey @ 2001-01-11 22:17 UTC (permalink / raw) To: Xavier Leroy; +Cc: caml-list > Values of type "nativeint", "int32" and "int64" are boxed > (heap-allocated and handled through a pointer), while values of type > "int" are unboxed... > > > type loc = Cell of char * int * width > > | Slice of ... > > > > type loc' = Cell of char * nativeint * width > > | Slice of ... > > A "Cell" requires two more memory words in the latter case. Thanks for this very helpful reply. I think for simplicity, we may go with nativeint now. Another question: are there any tools that would enable us to track, e.g., how much memory is being occupied by instances of "Cell", or even just how many "Cells" might be live at a given moment? That way we could evaluate the potential savings in moving to int for some variants... Norman ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2001-01-12 9:09 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2001-01-10 18:25 questions about costs of nativeint vs int Norman Ramsey 2001-01-11 9:17 ` Cost of polymorphic variants over normal ones Sven LUTHER 2001-01-11 10:40 ` Alain Frisch 2001-01-11 10:44 ` Sven LUTHER 2001-01-11 14:50 ` Jacques Garrigue 2001-01-11 19:14 ` Markus Mottl 2001-01-11 18:34 ` questions about costs of nativeint vs int Xavier Leroy 2001-01-11 22:17 ` Norman Ramsey
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox