This document contains only my personal opinions and calls of judgement, and where any comment is made as to the quality of anybody's work, the comment is an opinion, in my judgement.
[file this blog page at: digg del.icio.us Technorati]
127.0.0.1
as the server address, and only the local server has to be
re-configured and/or restarted.
resolveris used by almost every application, and since I use several browser style applications an HTTP proxy service is also widely required. Consider the latter case again: sure, the details of the web proxy server can be configured in a
proxy.pac
file, or for simpler applications in
the environment variable http_proxy
; but it is
already two places, and at least in the latter case
applications have to be restarted if the server contact
details change. The overall principle is that applications
don't really need to know which server provides the service,
just the address of some intermediary that knows. And here
there is a chance to talk about a bigger story, interposition,
and in particular the transparent one.
hooksfor functions). Another form of advising can be done by using the GNU Binutils
LD_PRELOAD
with the
dlsym(RTLD_NEXT,
...)
function call.
opaque capabilitiesand semantics similar to those of the
become:
method of the
recently mentioned
Smalltalk-80 language: Given two
capabilities it swaps them everywhere. Therefore what can be
done is to create a capability, say I to process
ADVISOR, the entity to be interposed, and then
exchange:
it with the capability, say
S to SERVER, the entity to be
interposed to. The result is that S will then
denote ADVISOR and then I will
denote SERVER, with the result that all
operations on S intended for SERVER
go to ADVISOR and the latter has I
denoting SERVER to pass-on, if necessary, such
operations to the originally denoted entity.
127.0.0.1
as
the server address; in this way only the per-node servers need
to be reconfigured, and they are often less numerous and
easier to reconfigure than the applications. These per-node
servers are an extra level of indirection interposed between
the applications and the resources they need, and they buy
some valuable degrees of freedom (at the cost of some small
extra load on each node).
interpositoryservers could be the same in all workgroups, and to have NAT applied to each workgroup, under the plausible assumption that the clients in the workgroup did not need to be addressable from outside it. This practice still has merit for various reasons, but is no longer necessary.
SMTP.
group1.Example.com
or IPP.
group1.Example.com,
and then I configure per-workgroup DHCP servers with a DNS
server list like
DNS.group1.Example.com DNS.Example.comand a resolver search path such as
group1.Example.com Example.comand then I configure the per-node server dæmons with relative names like SMTP and
proxy
and IPP
(this last not strictly necessary as
IPP
works well with broadcasts). This achieves some desirable
extra flexibility and resiliency, for example consider SMTP:
localhost
as
their mail server name. The local server receives each
message and queues it.SMTP
as the smart-host. This will resolve to the workgroup server or to the site server depending on what is available.
SMTP
relative domain name will just resolve
to the one for the new workgroup without any changes.NAPTR
and
SRV
resource records are used to provide applications with
pointers to which servers provide which services, but these
resource records are not widely supported by servers or
applications. The simple naming convention I use by default
can be used anyhow, and I have written some time ago a
nice example
of using that and the new resource records to complement
non-transparent interposition./usr/share/yumex/yumex
)
as follows:
#!/bin/bash # # Run yumex main python program. # /usr/bin/python /usr/share/yumex/yumexmain.pyc $*in which there are no less than three (and arguably four) quite objectionable entry-level misfeatures.
PC1
to another PC an ISO disc image:
PC1$ ls -ld grml_0.8.iso -rw-r--r-- 1 pcuser01 pcuser01 730511360 Oct 17 16:59 grml_0.8.isousing both UDP:
PC1$ time /usr/bin/nc -u -v -v -v 10.0.22.22 3333 < grml_0.8.iso PC2.Example.com [10.0.22.22] 3333 (?) open sent 679460864, rcvd 0 real 0m9.025s user 0m0.060s sys 0m2.258sand TCP:
PC1$ time /usr/bin/nc -v -v -v 10.0.22.22 3333 < grml_0.8.iso PC2.Example.com [10.0.22.22] 3333 (?) open sent 730511360, rcvd 0 real 0m6.846s user 0m0.056s sys 0m1.219sSo we have like 75.3MB/s in UDP (and the transmissions ends early, as probably some error happened) and a remarkable 106.6MB/s in TCP. By using
strace
it appears that
in both cases the sender and receiver are using 8KiB blocks. I
was running vmstat 1
on both PCs. For TCP on the
sender the relevant section looks like
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 2 2432 375644 55096 319564 0 0 62244 56 14726 2070 1 6 57 36 0 3 2432 298972 55172 395928 0 0 76616 36 17552 2363 1 8 14 77 0 1 2432 225884 55248 469172 0 0 73032 4 16978 2187 1 7 21 72 0 1 2432 151516 55328 543192 0 0 74312 16 17227 2145 0 7 57 36 0 1 2432 75484 55404 619296 0 0 76108 0 17674 2185 1 8 57 34 0 1 2432 16860 38384 694816 0 0 77004 0 17856 2212 1 9 58 33 0 1 2432 15452 19060 715700 0 0 75592 76 17531 2940 1 10 57 33 0 1 2432 16484 17980 717820 0 0 70724 0 16492 2134 1 9 56 34 0 1 2432 15844 17968 721472 0 0 77260 12 18013 2309 1 9 58 33That looks fine, reading about 70-75MB/s from the disk (
PC1
has a rather quick
SAS
hard disc) and a fairly low (considering...) 14,000 interrupts/s
and 2,100 context switches/s, taking about 9% CPU time, on a
Core 2 at 1.9GHz. On the sender there is a bit more strain:
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 1 0 236 320828 10352 455568 0 0 0 0 2184 1275 1 1 97 0 0 0 236 320828 10352 455568 0 0 0 0 32286 5385 2 30 67 0 1 0 236 320828 10352 455568 0 0 0 0 34059 5898 2 35 64 0 1 0 236 320828 10360 455560 0 0 0 16 31124 4904 1 29 71 0 1 0 236 320828 10368 455552 0 0 0 28 33264 5366 1 31 68 0 0 0 236 320828 10376 455544 0 0 0 28 32893 5058 1 30 68 0 0 0 236 320828 10376 455544 0 0 0 0 33104 5279 1 31 69 0 1 0 236 320828 10376 455544 0 0 0 0 34030 6114 2 33 65 0 1 0 236 320828 10384 455536 0 0 0 12 31005 4931 2 28 71 0 0 0 236 320828 10384 455536 0 0 0 0 33149 5293 1 31 68 0 0 0 236 320952 10384 455536 0 0 0 0 16770 2976 3 15 82 0That is about 33,000 interrupts/s and 5,000 context switches/s and that takes about 30% system CPU time on a Pentium 4 at 3.2 GHz.
/dev/zero
as data source
between PC1
and SRV1
(which is a
small enterprise levelDell server) and got some more fairly impressive and interesting results. When sending from
PC1
to SRV1
(time and
vmstat 1
output first on PC1
and
then on SRV1
:
PC1$ dd bs=4k count=250000 if=/dev/zero | time /usr/bin/nc -v -v -v SRV1 3333 SRV1.Example.com [10.0.5.120] 3333 (?) open 250000+0 records in 250000+0 records out sent 1024000000, rcvd 0 0.15user 2.57system 0:09.32elapsed 29%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+269minor)pagefaults 0swapsthere is this
vmstat 1
output on PC1
(sender):
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 2432 24068 38792 713128 0 0 0 0 1263 757 1 1 98 0 1 0 2432 23956 38792 713128 0 0 0 0 5563 29552 2 10 89 0 1 0 2432 23956 38792 713128 0 0 0 0 9601 57596 2 23 75 0 1 0 2432 23764 38792 713128 0 0 0 0 9765 58627 3 23 75 0 0 0 2432 23828 38792 713128 0 0 0 0 9717 57641 2 23 75 0 0 0 2432 23860 38792 713128 0 0 0 0 9718 58734 2 24 74 0 0 0 2432 23860 38808 713112 0 0 0 80 9807 58052 3 23 72 2 0 0 2432 23860 38808 713112 0 0 0 0 9788 58260 3 23 74 0 0 0 2432 23828 38808 713112 0 0 0 0 9844 59433 3 23 74 0 0 0 2432 23828 38808 713112 0 0 0 0 9777 59181 2 23 74 0 0 0 2432 24084 38808 713112 0 0 0 0 6380 34628 2 13 85 0 0 0 2432 24084 38808 713112 0 0 0 0 1375 1195 1 1 98 0and on
SRV1
(receiver):
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 990992 510860 130560 0 0 0 0 1617 3213 0 0 99 0 0 0 0 991000 510860 130560 0 0 0 0 7987 15598 0 4 96 0 1 0 0 991000 510860 130560 0 0 0 0 9032 17733 1 5 95 0 0 0 0 991000 510860 130560 0 0 0 4 9000 17638 0 5 95 0 1 0 0 991000 510860 130560 0 0 0 0 9020 17658 1 5 95 0 0 0 0 991000 510860 130560 0 0 0 0 8999 17496 1 5 95 0 1 0 0 991000 510860 130560 0 0 0 0 9017 17548 1 5 95 0 1 0 0 990872 510860 130560 0 0 0 312 9010 17806 1 4 95 0 0 0 0 990936 510860 130560 0 0 0 264 9037 17821 0 5 95 0 0 0 0 990936 510864 130556 0 0 0 224 9018 18008 1 5 95 0 0 0 0 990936 510864 130556 0 0 0 0 2356 4447 0 1 99 0 0 0 0 990872 510864 130556 0 0 0 276 1082 2105 0 0 100 0The same for sending data from
SRV1
to
PC1
:
SRV1$ dd bs=4k count=250000 if=/dev/zero | time /usr/bin/nc -v -v -v PC1 3333 PC1.Example.com [10.0.10.1] 3333 (?) open 250000+0 records in 250000+0 records out sent 1024000000, rcvd 0 0.17user 2.75system 0:08.73elapsed 33%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+209minor)pagefaults 0swapswith
vmstat 1
output for PC1
(receiver):
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 2432 28516 38960 708280 0 0 0 0 1195 1107 0 1 99 0 0 0 2432 28548 38960 708280 0 0 0 0 1169 447 1 0 99 0 1 0 2432 28548 38960 708280 0 0 0 0 6455 10919 1 4 96 0 1 0 2432 28532 38960 708280 0 0 0 0 17553 33503 2 13 85 0 1 0 2432 28524 38960 708280 0 0 0 0 17605 33397 2 12 86 0 1 0 2432 28524 38960 708280 0 0 0 0 17693 34191 3 14 84 0 1 0 2432 28524 38960 708280 0 0 0 0 17508 33054 1 12 87 0 1 0 2432 28524 38960 708280 0 0 0 0 17424 32889 1 12 87 0 1 0 2432 28524 38960 708280 0 0 0 0 17466 32963 1 12 87 0 1 0 2432 28588 38960 708280 0 0 0 0 17446 32952 1 9 90 0 1 0 2432 28588 38960 708280 0 0 0 0 17484 32994 1 11 89 0 0 0 2432 28716 38960 708280 0 0 0 0 7439 12942 1 5 94 0 0 0 2432 28716 38960 708280 0 0 0 0 1152 342 0 0 100 0and
SRV1
(sender):
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 0 991000 510904 131036 0 0 0 0 1062 2135 0 0 100 0 0 0 0 991064 510904 131036 0 0 0 0 1035 2097 0 0 100 0 2 0 0 990616 510904 131036 0 0 0 0 7950 55000 1 11 88 0 0 0 0 990680 510904 131036 0 0 0 0 9024 63327 1 13 86 0 0 0 0 990616 510904 131036 0 0 0 0 9029 63309 1 12 87 0 2 0 0 990552 510904 131036 0 0 0 32 9028 63410 1 12 86 0 0 0 0 990488 510904 131036 0 0 0 328 9063 63548 1 13 86 0 0 0 0 990488 510912 131028 0 0 0 72 9025 63361 1 12 87 0 2 0 0 990488 510916 131024 0 0 0 460 9071 63884 1 12 87 0 2 0 0 990488 510916 131024 0 0 0 128 9055 63380 1 13 85 0 0 0 0 990680 510916 131024 0 0 0 0 7875 54301 1 11 88 0 0 0 0 990680 510916 131024 0 0 0 0 1020 2143 0 0 100 0In both case around 1GB is transmitted in about 9s, for over 100MB/s which is pretty amazing. Interestingly high CPU and interrupt numbers though:
PC1
(CPU: 2x Core 2@1.9GHz,
NIC: Broadcom BCM5754) it takes nearly 9,000
interrupts/s to send (and 58,000 context switches/s) and
23% of CPU, the 17,000 interrupts/s and 32,000 context
switches/s for receiving consume only 12% of CPU time.SRV1
(CPU: 2x Xeon@3GHz, NIC:
2x Intel 82541GI/PI) receiving consumes only 5% of CPU
time, with 9,000 interrupts/s and 17,000 context
switches/s while sending costs 12% of CPU time with
9,000 interrupts second (same as for receiving) and
63,000 context switches/s.jumbo framesno longer are indispensable to achieve decent bandwidth, as modern CPUs and systems can sustain amazingly high interrupt and context-switch rates; also some network interfaces seem to have fairly effective offloading and interrupt coalescing. But jumbo frames are still rather useful for 10gb/s Ethernet especially if lower CPU utilization and latency are both desired. Note also that such numbers are unlikely to be achievable with consumer grade equipment.
top
:
top - 23:04:36 up 6:53, 5 users, load average: 0.88, 0.34, 0.15 Tasks: 150 total, 3 running, 144 sleeping, 0 stopped, 3 zombie Cpu0 : 32.2%us, 6.6%sy, 0.0%ni, 60.5%id, 0.0%wa, 0.0%hi, 0.7%si, 0.0%st Cpu1 : 52.7%us, 23.0%sy, 0.0%ni, 24.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1033328k total, 985904k used, 47424k free, 0k buffers Swap: 5140760k total, 32k used, 5140728k free, 577660k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6967 root 25 0 302m 209m 15m R 99 20.8 15:47.10 python 8931 root 15 0 168m 38m 18m S 0 3.8 0:28.68 firefox-bin 6891 root 16 0 122m 14m 10m S 0 1.5 0:05.84 nautilus 6977 root 15 0 112m 7380 5968 S 0 0.7 0:00.05 trashapplet 2790 nscd 16 0 106m 1048 772 S 0 0.1 0:00.09 nscd 6975 root 16 0 96996 10m 7172 S 1 1.0 0:07.24 wnck-applet 6889 root 15 0 86220 14m 9452 S 0 1.4 0:04.87 gnome-panel 6994 root 15 0 84116 10m 7580 S 0 1.0 0:02.99 mixer_applet2 6947 root 15 0 81704 8796 7316 S 0 0.9 0:00.08 nm-applet 3025 root 15 0 70324 43m 12m S 0 4.3 0:01.01 httpd 3114 apache 19 0 70324 31m 816 S 0 3.2 0:00.00 httpd 3115 apache 18 0 70324 31m 808 S 0 3.2 0:00.00 httpd 3116 apache 18 0 70324 31m 800 S 0 3.2 0:00.00 httpd 3117 apache 18 0 70324 31m 800 S 0 3.2 0:00.00 httpd 3120 apache 18 0 70324 31m 800 S 0 3.2 0:00.00 httpd 3121 apache 18 0 70324 31m 800 S 0 3.2 0:00.00 httpd 3122 apache 18 0 70324 31m 800 S 0 3.2 0:00.00 httpd 3123 apache 20 0 70324 31m 800 S 0 3.2 0:00.00 httpd 6909 root 15 0 41788 2576 1912 S 0 0.2 0:00.07 bonobo-activati 7043 root 15 0 41476 16m 7928 R 12 1.6 2:40.36 gnome-terminal 6925 root 15 0 40448 6784 5624 S 0 0.7 0:00.02 eggcups 6868 root 15 0 31544 6796 5532 S 0 0.7 0:00.91 gnome-settings- 6992 root 19 0 28580 9616 6652 S 0 0.9 0:02.90 clock-applet 6828 root 15 0 23528 18m 4180 S 1 1.8 2:59.41 XvncSince I am configuring this laptop it is still starting X by default in GNOME, but the virtual and resident memory sizes are still quite impressive, even for GNOME that is (the
python
process is the one running YumEx).Smalltalk, never mind the differences between the 72 and 76 languages with that word as part of their name. But I think that matters for various direct and indirect reasons:
paths(like
$PATH
) to find resources, and scan them until
they find it. Dreaming even more such paths would be dynamic,
that is they would be produced on demand.
/etc/resolv.conf
, which
is read by each application as it starts. This means that if
the path needs changing, applications should be restarted.
Also in many cases clients for a service don't use paths, but
servers do, often as part of a master-slave, or cached, or
similarly clustered service relationship. Also, server
unavailability often hangsthe client, which is another annoyance. In general, client service access libraries are designed with less resilience and tolerance for errors than server dæmons.
/etc/resolv.conf
contains just nameserver 127.0.0.1
, and I run a
DNS server instance on each client.
This instance is configured to use a workgroup DNS server as a
forwarder, and this is similarly configured as a slave for the site DNS servers. Similarly for NTP, NIS (and even LDAP directories where useful), SMTP, HTTP proxying, and of course IPP (where servers send each other browser lists and client based servers thus autoconfigure). For MSA style server for protocols like POP3 and/or IMAP4 once can configure things so that instead of having e-mail delivered to a single site or even inter-site wide mailbox repository, it is delivered to per-group or even per-PC servers. For example the MTA for an organization could, on receiving a message for user
@
example.com
forward it for delivery to a workgroup server as
user@
acct.example.com
which could either store it locally or forward it again to the
user's PC as
user@
pc12.acct.example.com.
127.0.0.1
as the server address,
and then the local server can be reconfigured and restarted
with minimal disruption of existing applications. This is of
course useful not just to minimize the impact of service
disruptions, but also for intentionally disconnected usage,
for example for laptops.Infrastructure services | Electrical power
Ambient cooling. Network cabling. |
Basic services | Node-local storage.
Node-local processing. Internal network bridging and routing. External network routing (hopefully not intersite bridging!). Network firewall. |
System services | DHCP
and/or BOOTP,
TFTP
NIS or LDAP. NTP. and DNS Backup. Updates. |
Basic user services | NFS
and/or SMB
SMTP, POP3 and/or IMAP4 CVS and/or SVN |
Optional user services | DBMS
access.
Jabber and/or IRC, NNTP. LPR and/or IPP VoIP |
Remote access services | FTP,
RSYNC
HTTP, HTTP proxying SSH, VPN |
:->
), but not much work can continue if power is
missing. At the same time though the impact is larger: e-mail
can be postponed, but if nobody at a site can send e-mail for
a long period of time this can impact a lot of activities. I
would think therefore that for smaller scope services
redundancy and isolation are more important (preventing
widespread interruptions), for wider scope ones it is quick
time to repair (making interruptions shorter).
message passingto indicate both the passing of messages, as opposed to the sharing of state, in distributed programming, its proper meaning, and dynamic overloading in ordinary, shared state procedure calls.
classes.
Term | Smalltalk-72 | Smalltalk-76 |
---|---|---|
object | A self contained potentially active entity that has
an input stream (the transcript) it can parse and that can send token to the input stream of other objects and that can be cloned. Each object potentially interprets its input stream differently and in parallel. |
A passive value that is an instance of a type
description called a classwhich defines a set of procedures that can be applied to values instantiated from it. |
script | A set of rules defining how to parse the object's input stream and react to them. | Not part of the language. |
method | Not part of the language. | A procedure body bound to a particular name. |
message | A stream of tokens copied from one active object to another. | A procedure name (called selector) and list of parameters, following a passive value to which the procedure is to applied. |
message send | Copying a sequence of tokens to another object. | Finding the class of an object, looking up the name of the procedure in the class table of methods, and callin the method if one exists with the same name. |
selectorfollows the value and precedes the arguments (infix syntax).
The Benefits of the Message Discipline
Adding a new class of data to a programming system is soon followed by the need to print objects of that class. In many extensible languages, this can be a difficult task at a time when things should be easy. One is faced with having to edit the system print routine which (a) is difficult to understand because it is full of details about the rest of the system, (b) was written by someone else and may even be in another language, and (c) will blow the system to bits if you make one false move. Fear of this often leads to writing a separate print routine with a different name which then must be remembered. In our object-oriented system, on the other hand, printing is always effected by sending the messageprinton: s
(wheres
is a character stream) to the object in question. Therefore the only place where code is needed is right in the new class description. If the new code should fail, there is no problem; the existing system is unmodified, and can continue to provide support.
The class organization and message discipline ensure that if the original message protocol is supported, then all code outside the class will continue to work without even recompiling. Moreover, the only changes required will all be within the class whose representation is being changed.The quotes above clearly describe the advantages of dynamic overloading as opposed to using
Modularity is not just an issue of "cleanliness." If N parts depend on the insides of each other, then some aspect of the system will be proportional to N-squared.
Such interdependencies will interfere with the system's ability to handle complexity. The phenomenon may manifest itself at any level: difficulty of design, language overgrown with features, long time required to make a change or difficulty of debugging. Messages enforce an organization which minimizes interdependencies.
case
or
switch
statements and more weakly those of the
module-based decomposition paradigm. But look a bit further
down and the confusion is apparent:
Another benefit of leaving message interpretation up to the target objects is type independence of code.This quote shows that the implementar of the system himself is still under the delusion that in Smalltalk-76 each object independently parses an input stream, where instead selectors are strictly resolved by looking them up in class based tables, returning method addresses.
In theThe above quote instead is about genericity of code, where a bit of code is generic with respect with all the classes that implement the same procedure names.Rectangle
example, the code will work fine if the coordinates areInteger
orFloatingPoint
, or even some newly-defined numerical type. This allows for much sharing of code, and the ability to have one object masquerade as another.
When a send bytecode is encountered, the interpreter finds theEven more clearly here:CompiledMethod
indicated by the message as follows:
- Find the message receiver. The receiver is below the arguments on the stack. The number of arguments is indicated in the send bytecode.
- Access a message dictionary. The original message dictionary is found in the receiver's class.
- Look up the message selector in the message dictionary. The selector is indicated in the send bytecode.
- If the selector is found, the associated CompiledMethod describes the response to the message.
- If the selector is not found, a new message dictionary must be searched (returning to step 3). The new message dictionary will be found in the superclass of the last class whose message dictionary was searched. This cycle may be repeated several times, traveling up the superclass chain.
Methods correspond to programs, subroutines, or procedures. Contexts correspond to stack frames or activation records. The final structure described in this section, that of classes, is not used by the interpreter for most languages but only by the compiler. Classes correspond to aspects of the type declarations of some other languages. Because of the nature of Smalltalk messages, the classes must be used by the interpreter at runtime.It is just unfortunate that the Smalltalk-72 terminology is so misleading when applied to Smalltalk-76 and its successors. By the way, the other great terminological confusion is that in C++ the word
objectmeans
memory areaand not
class instance, but that's another story...
overloadingand
genericity.
symbolsusually and happens when the same symbol resolves to different values in different contexts. For example in this C-like code fragment:
void f() { int i; { float i; i = 1.0f; } { char i; i = '2'; } i = 3; }the symbol
i
used the name of three distinct
variables is overloaded and is bound to three different values
(all three of reference type, but with different type
constraints). Overloading gives rise no ambiguity, as in the
example above, if context makes clear which
particular binding of the symbol is intended.
manifest, as in
int sqr(const int x) { return x*x; } float sqr(const float x) { return x*x; } void f() { int i = sqr(2); float j = sqr(2.0f); }but it can also be dynamic, when the type (or the value) is not manifest. Now in way of principle static or dynamic overload resolution can be applied in way of principle to any one or all arguments; however in many if not most OO languages static overloading applies to all parameter, but dynamic resolution can only apply to the first, or
distinguished, parameter.
classstructure tend to have a special invocation syntax for class
methodswhich is usually entirely futile, as an invocation of the form
objectRef.methodName(argsList)is in effect an infix form just equivalent to the usual prefix form
methodName(objectRef,argsList)(except of course in Actor systems). As mentioned above the one peculiarity of the infix from is that it distinguishes syntactically the first argument, which is dinstuished semantically in most language by being the only one on which dynamic overload resolution can be done.
genericity, which is a property of a part of program text (and not of a symbol like
overloadingor of a program like semantics): a program text is generic if the intersection of the overloadings of the symbols contained in it is not a single interpretation. So for example this program text:
return (x > 0) ? x : -x;is generic as long as the
return
, >
,
unary -
and ? :
operators all
have more than one binding, and the intersection is multiple,
for example when they are all defined for int
and
float
.
x
can be of any type
for which the operators listed above are defined. The
C++ language has almost unbounded,
implicit genericity: the only bounds in a C++
templatecan be to restrict a free variable to be a template, which is required by obscure syntactical reasons.
max(a,b) { return (a > b) ? a : b; }is valid and useful for many types of values, all those for which a partial ordering operator is defined. However both overloading and genericity also have a downside: that they can be abused when the same symbol or program text is used even if the semantics are very different, thus inviting confusion. For example it is all right if in the
max
example
above the operator symbol >
is overloaded with
respect to integers and floating point values, but it is
rather less so if the overloading is extended to binary trees,
to indicate inclusion, as that strains similarity of semantics
that makes overloading and genericity useful as a shorthand.webapps, with the added complication that they be accessed from an Apache server used as reverse proxy. One could achieve this simply with some Apache configuration like (note the two distinct
ServerName
s):
<VirtualHost *:80> ServerName author.Example.com ServerAdmin webadm@Example.com DocumentRoot "/usr/share" ProxyPass / "ajp://localhost:8071/author" ProxyPassReverse / "ajp://localhost:8071/author" <VirtualHost *:80> ServerName WWW.Example.com ServerAdmin webadm@Example.com DocumentRoot "/usr/share" ProxyPass / "ajp://localhost:8071/publish" ProxyPassReverse / "ajp://localhost:8071/publish"that is forwarding two different domains to two different webapps on the same Tomcat domain and port. But this is impossible if the local part of a URL must be exactly the same in the Apache front-end and in the Tomcat back-end, as when the webapps generate absolute paths in their responses.
<VirtualHost *:80> ServerName author.Example.com ServerAdmin webadm@Example.com DocumentRoot "/usr/share" ProxyPass / "ajp://localhost:8071/" ProxyPassReverse / "ajp://localhost:8071/" ProxyPassReverseCookiePath "/" "/" ProxyPassReverseCookieDomain "localhost" "localhost" <Location /> Options +IncludesNoExec +Indexes </Location> </VirtualHost> <VirtualHost *:80> ServerName WWW.Example.com ServerAdmin webadm@Example.com DocumentRoot "/usr/share" ProxyPass / "ajp://localhost:8072/" ProxyPassReverse / "ajp://localhost:8072/" ProxyPassReverseCookiePath "/" "/" ProxyPassReverseCookieDomain "localhost" "localhost" <Location /> Options +IncludesNoExec </Location> </VirtualHost>
localhost
is that the
Tomcat 5 is the back-end for an Apache front-end, and it
is good to have it bound just to localhost
.
webapps for the same domain on different ports with Tomcat is then somewhat unobvious because Tomcat has a slightly odd design and anyhow its documentation is a bit confusionary as to which bits and pieces fit together and match which parts of the incoming request URL.
servlets, where usually the servlet is identified by the fist component of the local part of the URL. Things become a little more complicated if there are multiple real or virtual
hosts, and/or different ports on the same domain name.
connectors, and exactly one
engine.
port.
valves and
realms, and at least one
host.
webapps (procedure name) bound to that host.
protocol://domain:port/first/restits resolution to a servlet goes like this:
connectorin some
service. This selects a particular service for further processing, and thus a particular set of
valves and
realms.
hostin that
service. If there is no HTTP/1.1
Host:
header to indicate a name based virtual host, then the
default
host in that
serviceis matched.
hostis identified, its
appBase
directory is selected.webappin the selected directory, which is instantiated as a
servletand passed the following rest of the local part of the URL as its parameters. A particular webapp may be instantiated into several different flavors of servlet by using a different
contextwith different parameters for the instantiation.
ROOT
and there can be only one per
appBase
directory, no matter how many addresses
or ports the connectors are bound to.
ROOT
webapp,
but that is not really the case because there can be a
different bound port and a different engine but with hosts
with the same name per engine. Thus binding distinct
appBase
directories on the same domain to
different incoming ports requires multiple services, for
example as follows:
<Service name="Backend-1"> <Connector debug="0" protocol="AJP/1.3" port="8071"/> <Connector debug="0" protocol="HTTP/1.1" port="8081" redirectPort="8091" acceptCount="10" connectionTimeout="20000" minProcessors="1" maxProcessors="5" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/plain" noCompressionUserAgents="gozilla,traviata" scheme="http" secure="false" enableLookups="true" useURIValidationHack="false"> </Connector> <Engine debug="0" name="Engine-1" defaultHost="localhost"> <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve" directory="/var/log/tomcat5" prefix="catalina_" suffix="_1.log" pattern="combined" resolveHosts="false"/> <Realm debug="0" className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host debug="0" name="localhost" appBase="webapps1" unpackWARs="true" autoDeploy="true"> </Host> </Engine> </Service> <Service name="Backend-2"> <Connector debug="0" protocol="AJP/1.3" port="8072"/> <Connector debug="0" protocol="HTTP/1.1" port="8082" redirectPort="8092" acceptCount="10" connectionTimeout="20000" minProcessors="1" maxProcessors="5" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/plain" noCompressionUserAgents="gozilla,traviata" scheme="http" secure="false" enableLookups="true" useURIValidationHack="false"> </Connector> <Engine debug="0" name="Engine-2" defaultHost="localhost"> <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve" directory="/var/log/tomcat5" prefix="catalina_" suffix="_2.log" pattern="combined" resolveHosts="false"/> <Realm debug="0" className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Host debug="0" name="localhost" appBase="webapps2" unpackWARs="true" autoDeploy="true"> </Host> </Engine> </Service>The above two services (meant to be the authoring and publication side of a web CMS like Magnolia) are selected depending on a port match for the relevant
connector, for ports bound to the
localhost
address in both cases; but the two
engines have
hosts with different
appBase
s for the same domain name, into
which different webapps are symbolically linked in as
ROOT
.
just workthanks to automagic spanning tree buildup). Or it may be due to scope creep, where it is very tempting to just slap together LANs together temporarily by bridging (for example when corporations merge), and little by little a monster arises.
> >> FreeBSD 6.0 NFS client seems keep trying NFS access forever after NFS > >> TCP connection is (half?) closed.as in closed by the server but not by the client, and the client would freeze waiting for replies. The freeze was quite long, like 15-20 minutes, because the Linux TCP stack uses a very long timout for retries:
tcp_retries2 (integer; default: 15)This long Linux default was quite inappropriate in the case because all NFS-over-TCP connessions were on the same site, with high bandwidth and low latency. If one of the connection ends is closed for whatever reason, the connection at the other end should be closed too rather sooner, without so many retries.
The maximum number of times a TCP packet is retransmitted in established state before giving up.
The default value is 15, which corresponds to a duration of approximately between 13 to 30 minutes, depending on the retransmission timeout.
The RFC 1122 specified minimum limit of 100 seconds is typically deemed too short.
tcp_retries
would
IP_RECVERR (defined in <linux/errqueue.h>)as that for example should reflect ICMP unreachability notifications to the application level.
Enable extended reliable error message passing. When enabled on a datagram socket all generated errors will be queued in a per-socket error queue. When the user receives an error from a socket operation the errors can be received by calling recvmsg(2) with the MSG_ERRQUEUE flag set.
localhost
as the server for all those
services.search
in
/etc/resolv.conf
, in particular when using DHCP
it is possible to make the configuration of group servers and
clients almost identical and quite flexible, minimizing
maintenance effort, and maximizing resilience and
upgradeability. Sometimes I like to have the same private
address range in each workgroup, with SNAT at the workgroup
router; conceivably it might even be the
169.254.0.0/16 link local subnet
(discussed also in
RFC 3297).
non-standardtechnology, I feel that the best option is to have both a per-client and per-group file area, with the main one being the per-client one, and to take on the annoyance of backing up the per-client file area using something like Amanda or even just plain RSYNC (or systems based on it like rsnapshot).
better the devil you know. And I just found this fabulous example of VLAN advocacy:
These virtual networks offered a new networking solution that could offer QoS due to its priority scheme and cost-saving solutions for businesses. With VLANs, there was no longer a need to physically move around office employees to connect them to the same network as their counterparts on different floors. With the help of a few Ethernet switches, the employees on the tenth floor could get all their traffic tagged with the same VLAN ID as the employees on the second floor. This method allowed them to be on the same network "virtually", and thus eliminate the expensive moving costs.which to me sounds quite peculiar (to say the least), as what matters is access to services, not to LANs, and the impression I get is reinforced by this fascinating argument:
Better performance than a routed networkApart from the
A network that uses VLAN technology is a switched network and therefore will perform better than a routed network, mainly because of the routing overhead required.
In a switched network, when using a shared link, the size of each VLAN can be decreased, which results in fewer collisions because each VLAN is an independent collision domain as far as the network layer is concerned.
Furthermore, it is also possible to group a large LAN to smaller VLANs and reduce broadcast traffic overall as each broadcast will be sent on to the relevant VLAN only.
the routing overhead requiredwhich seems to confuse latency with bandwith, and that routing delivers much better locality of traffic, somehow it is forgotten that essentially all current Ethernet networks are based on switching and full duplex links, and there are no collisions.
A VLAN is an administratively configured LAN or broadcast domain. Instead of going to the wiring closet to move a cable to a different LAN, network administrators can accomplish this task remotely by configuring a port on an 802.1Q-compliant switch to belong to a different VLAN. The ability to move endstations to different broadcast domains by setting membership profiles for each port on centrally managed switches is one of the main advantages of 802.1Q VLANs.I especially like the
Instead of going to the wiring closet to move a cable, which blithely abstracts away a very big difference between having two physical LANs or a single physical LAN shared by multiple VLANs.
Taking a pristine hard drive and installing a minty fresh copy of Windows XP, we made a conscious decision to banish all thoughts of autoupdates, Windows firewall and anti-malware protection.
Internet Explorer awakened with nary a sniffle or judder, and off we went in pursuit of webbery. For a couple of hours.
Unknown programs loading into the system memory popped up on-screen and vanished as quickly, but left us with the feeling the test was nearly over. And so it proved, when IE would only work in ten minute bursts, its short lifetime filled with dire warnings of impending doom and an infinity of smiley-hawking popups. Each collapse required a reboot. On a Spybot check, 188 of malware were detected: enough to render the PC unusable.Seems pretty clear to me. There are indeed lots of people who think that owning other people's PCs is profitable (and spyware is a quite profitable business, unfortunately).
The final time of death? Two hours thirty minutes.
.orgarea.
buyer beware, but when buyers do not, everybody suffers in a highly networked society, as trojans and spyware programs have detrimental consequences well beyond their
buyers.
trusted computing) and third parties. Control of many people's PCs is an increasingly valuable goal.
* 1394c uses the same physical cable at 1000BASE-T, 100BASE-TX, 10BASE-Twhich sounds to me like a clever way to recycle proven mass market hardware for a proven but less popular IO protocol.
- Same connector and pin-out
This is by no means the first time I've witnessed this process whereby outsourcing effectively fossilises a company's IT infrastructure - the finance director makes the outsourcer take on the role of a refusenik, dreaming up all sorts of reasons why this or that enhancement or economy of scale can't be considered, because it will trigger an avalanche of contractual and staffing changes in the outsourcer.Designing effective incentives is often difficult, the more so in IT projects which are usually part of cost, not profit, centres.
Between 40% and 50% of Brits won't make the effort to reclaim their devices from lost property offices, preferring to let their company pick up the bill or claim the costs back from their insurance company, [ ... ] Heathrow alone has around five laptops and ten mobile phones handed in each day.
There was a great deal of work put into the original 6-pin FW400 connector so that it would be mechanically robust. One of the primary features is that the moving parts were all in the *plug* (all connectors have moving parts ... those little springy bits that apply pressure and make sure the connection is good and tight). This way the part of the connector/socket system that wears out is in the cable. When something goes wrong (as it will in any mechanical system), you throw out the cheap, easily replaceable component ... i.e., the cable. Unfortunately, with the 4-pin design, the moving parts are in the socket ... so when you buy a slightly off-spec cable at your favorite cheapo retailer and plug it into your camcorder, you might ruin the camcorder. With the 6-pin design, your ruin the cable.Ideally the prongs would be in the cable and the laptop would have the holes. A smart friend pointed out that as a rule active electrical components have the holes, as that's safer. But then one could have prongs in a recessed position. Not a trivial issue though.
You set a parameter for a style element, and that setting falls to the next element unless you provide it with a different element definition. This sounds like a great idea until you try to deconstruct the sheet. You need a road map. One element cascades from here, another from there.Well, yes, but the problem is not so much with cascading, but that the specific rules are somewhat odd.
One wrong change and all hell breaks loose.Well, that's true of most notations, and does not seem a good point to me. Debugging of CSS is necessary. However this subsidiary point is interesting:
If your Internet connection happens to lose a bit of CSS data, you get a mess on your screen.Indeed, and highly structured markup of this sort is not that resilient to mishaps. However the fix is usually easy, reloading.
The real problem is that no two browsers?let alone no two versions of any one browser interpret CSS the same way! The Microsoft browser interprets a style sheet one way, Firefox interprets it another way, and Opera a third way. Can someone explain to me exactly what kind of "standard" CSS is, anyway? There actually are Web sites that mock this mess by showing the simplest CSS code and the differing results from the three main browsers and the Safari and Linux browsers. The differences are not trivial. And because of the architecture of this dog, the bugs cascade when they are part of a larger style sheet, amplifying problems.Well, again a highly structured notation like CSS is indeed fragile to mishaps, and implementation problems happen with everything, so the following conclusion:
And what's being done about it? Nothing! Another fine mess from the standards bodies.seems unjustified. But there is a good point here: the definition of CSS is subtle and easy to misimplement. I reckon that there is little evidence that higher technical ability leads to greater market success, and standards therefore should be simple and easy to understand, and difficult to misunderstand.
professionalcameras seem to have a flash hotshoe, and they tend to be both bigger and more expensive than I'd like. I blame dumb consumers for not realizing how important is to have the ability to use a flash with a significant offset from the camera lens (in particular: hold the camera in the right hand, and the flash in the left hand, high and pointing down or viceversa to the ceiling).
xDmemory cards, which are less common and slower than the more common
SDones; but then there is a faster grade of xD memory cards. Too bad that very few cameras nowadays use
CompactFlashmemory cards, as they are rather preferable as they come in bigger sizes and since they have an ATA interface they can be rather quicker. Also, because of the ATA interface it is easier for the card manufacturer to put in sparing logic for overused blocks.
iSCSIand
SANand why bother, and as to iSCSI, the difference between bus protocol and command protocol.
bus) between the host and storage device and is about transferring bytes between host and storage, whether the bytes be commands or data.
integrated drive electronicsthe bus protocol was also the command protocol, with things like operation codes like read, write or seek being explicit at the bus level; currently instead command or data packets are encoded, transferred over the bus, and decoded by the IDE part of the storage device. Which can be very sophisticated: contemporary disc drives can have hundreds of thousands to millions of lines of code of
firmwarewhich runs on embedded operating systems on fast 16 and even 32 bit CPUs with some MiBs of RAM.
tablespacesand not files, even if perhaps on recent Linux kernels this is no longer necessary (or one can use OCFS2).
I have a 6 disk RAID5, I just added another disk, I plan to use the kernel feature in 2.6.17 to "hot-add" an additional disk to the array (not a spare), then I plan to use xfs_growfs to grow the filesystem to the maximum size it can support.Fascinating example of having a 5+1 array and turning it into a 6+1 array
because we can.
My RAID is an IDE-SCSI system -- IDE disks, looks like SCSI to the host. It has 8 80GB drives in RAID 5, for about 560GB of usable space. I'd like it to be just one partition.A 7+1 RAID5 is a good way to push the boundaries, and making a single system out of it demonstrates courage
:-)
.All I know at this time for my RAID array is that there are 12 disks of 500 GB, so 11 * 500 GB of usable space (last disk for checksum), and it's not enough to know which value to set to sunit, it seems that sunit must not be equal to the size of one of the disk in my RAID array. I heard here and there about chunk size and stripe size. But I don't know what is the cunk size of a RAID array and how can I know it, (it's not me that bought this RAID array),At least the author did not setup himself this seemingly insane 11+1 setup, but seems to have forgotten than in RAID5 the parity is interleaved...
I have a 12 disk HW raid 5 with 128K stripe size. I built my 4k block XFS volume with sunit=256,swidth=2816. Everything is peachy ... or is it?Good question!
:-)
I have two external JBODs with 12 disks each. Each JBOD has two channels, 6 disks per channel, and each channel is connected to a QLogic ISP 10160 controller.Not only an 11+1 setup, but two, mirrored ones. Perfect combination of low performance and low resilience.
Each of the JBODs is built as an md raid5 (md1 and md2). Both raid5s are mirrored (md3).
but most people will have all disks configured in one RAID5/6 and thus it is not parallel any more.
hope this does not hold true for a 15x750GB SATA raid5. ;)Good that it is understood that RAID5 has dire write performance implications. I agree sadly that as stated most people will default to a wide RAID5, and quite entertaining to see someone going for a RAID5 as wide as 14+1. Way not to go!
The box contains 16x750GB SATA drives combined into a single 11TB raid5 partition using md, and this partition contains a single XFS filesystem.We are starting to get serious here: a single filesystem (that is, you lose any part of it, it is gone as a whole) on a 15+1 SATA RAID5. I would expect all the 16 drives to be of the same brand and model, and even from the same shipping carton
:-)
.This is in fact a 120 TB (not GB) filesystem that I am trying to build.This is probably my favourite. Not only the base unit is a 7+1 RAID5, but 80 of them are linearly concatenated in a single filesystem.
What I am attempting to do is to take 80 1.6 TB arrays ((8 x 250 GB Raid 5 arrays) 10 arrays from 8 separate SAN's). Use LVM to make one large volume, then use xfs to format and mount this as a single filesystem.
Any advice - or gotcha's would be appreciated.
ext2
usually
performs very well for that too, except that it and
ext3
handle
overwrites and resist fragmentation pretty badly, and thus
become seek-bound even on (logically) sequential
operations.ext2
and ext3
issue many more
IO operations per second than others.JFS demonstrated low write throughput. We discovered that this was partially due to truncating a multi-gigabyte file taking several minutes to execute.
However, the truncate time made up only half the elapsed time of each test. Hence, even if we disregarded the truncate time, JFS would still have had the lowest sustained write rate of all the filesystems.
controllerwhat is actually an host adater, but that is an incorrect use. It survives because a long time ago PC disc drives were not
IDE, and the controller was actually integrated on the WD100[36] host adapter (1 2), not the disc drive.
IDEqualified by the type of interface, as in
IDE/ATA.
write barriers. There are two variants of tagged queueing known as
TCQin the SCSI command protocol and
NCQin the SATA command protocol.
tagged queueingwas essential to achieving good disc read performance with many readers at different points of a disc. The reason for this is that tagged queueuing allows the host adapter or the disc itself to reorder requests in a way to minimize arm movements, trading a bit of latency for throughput. Without tagged queueing requests cause enough arm movement that the aggregate bandwidth is severely reduced. The minor effect of tagged queueing is also that requests get done asynchronously (as it implies
mailboxing), and thus can complete in a different order than the one they are issued in, which helps reclaim some latency lost to the batching of requests by position.
elevatoralgorithm to sort requests. For a while Linux has had five different elevator algorithms, and here is the difference between two of them (using a slightly different test from the previous one). First with the
noop
elevator and 4 streams:
# echo noop >| /sys/block/hdj/queue/scheduler; sh streams.sh 4 /dev/hdj # 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 213.285 seconds, 4.8 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 221.321 seconds, 4.6 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 221.379 seconds, 4.6 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 220.533 seconds, 4.6 MB/sThis is just 18.6GB/s but with the
anticipatory
scheduler throughput is a lot better:
# echo anticipatory >| /sys/block/hdj/queue/scheduler; sh streams.sh 4 /dev/hdj # 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 64.3318 seconds, 15.9 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 68.168 seconds, 15.0 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 68.0298 seconds, 15.1 MB/s 250000+0 records in 250000+0 records out 1024000000 bytes (1.0 GB) copied, 67.5332 seconds, 15.2 MB/sWell, surprises never end. It looks like that the anticipatory elevator batches and reorders as much as the elevator in the disc itself or the host adapter. I still prefer having a host adapter or discs with tagged queueing (and thus
mailboxing) as that allows reordering with lower latency and out-of-order completion, which are quite useful (except that some host adapters use very slow CPUs and thus they can add to latency by being slow to process requests, sometimes adding several milliseconds to each one). I have also tried the
deadline
elevator,
which has performance similar to the noop
one,
and again the cfq
elevator, which performs
sometimes like noop
and sometimes like
anticipatory
(probably depending on the order in
which the 4 dd
processes are scheduled).
streams.sh
script used above looks like:
#!/bin/bash let I=0 let N=${1-'4'} let C=250000 while [ $I -lt $N ] do (let S=$I*$C let D=$N-$I sleep $D && dd if=${2-'/dev/hda'} of=/dev/null bs=4k count=$C skip=$S)& let I=I+1 done
tagged queueingin the server's storage subsystem and some kind of acceleration in the clients' video cards, drivers and movie player.
base# sh streams.sh 1 /dev/hdj1 base# 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 6.6336 seconds, 61.7 MB/sThese 61.7MB/s are more or less the full speed of the underlying disc.
# sh streams.sh 4 /dev/hdj1 # 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 56.239 seconds, 7.3 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 58.2396 seconds, 7.0 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 57.2401 seconds, 7.2 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 55.3099 seconds, 7.4 MB/sWith 4 streams this disc cannot do more than less than half the bandwidth with a single stream. By comparison here is the video server with a 3ware host adapter with two equivalent 250GB discs in a RAID0 arrangement (for extra bandwidth of course):
# sh streams.sh 1 /dev/sda # 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 4.29543 seconds, 95.4 MB/sThe 95.4MB is quite good, without any special care RAID0 gives 50% bandwidth, and with 4 streams things are even better:
# sh streams.sh 4 /dev/sda # 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 16.1709 seconds, 25.3 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 15.7893 seconds, 25.9 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 16.7883 seconds, 24.4 MB/s 100000+0 records in 100000+0 records out 409600000 bytes (410 MB) copied, 14.7877 seconds, 27.7 MB/sNot only the aggregate bandwidth is not halved, but it is higher (103.3MB/s) probably because of better exploitation of the RAID0 parallelism.
HDRrendering, which is partially misnamed, and it is not really a technique, but the removing of a limitation or a bug. The idea is that in computing the luminosity of each pixel the result needs to be clipped, but not the intermediate values. So for example if a pixel reflects 20% of incident light and there are two 80% light sources, the luminosity of the pixel should be 32% and not 20%. To achieve this graphics cards were upgraded from 8 bit integer color intensity values to 32 bit floating point ones, for example to support Shader Model 3.0 in DirectX 9.0 which of course can be a lot slower (four times as many bytes to process, and floating point instead of 8 bit integer).
HDRis a misnomer for the idea of doing intermediate calculations in a higher precision than the final result: because there is no dynamic aspect to this, and arguably the range is not high, because the range of the final result does not change.
HDRwhich simulates the adjustement of the eye to light so that if one looks at a bright part of a scene the apparent light level goes down (as the eye adjusts to brightness) and if one looks at the dark parts of a scene the apparent light level goes up (as the eye adjusts to darkness). This is because the eye has a limit to the extent of light levels it can perceive, and dynamically adjusts its sensitivity up or down the scale.
HDR. This one works around the intensity range limits of cameras and screens by photographing the same scene a number of times with different exposures, and then combining the different photographs. This brings both the darker and lighter parts of the scene towards the middle of the range, so that in the resulting composite they seem to have much the same intensity. This has a very interesting effect, making the whole scene far more detailed and colourful than it appears otherwise, both to camera or eye. Part of the reason is that very dark areas or very bright ones do not appear colored to the eye (also because at low light levels the eye switches to black and white vision).