64-bit FORTH

Before I describe a 64-bit FORTH version, I need to explain something about the more-established, general 32-bit version of this low-level language. The 32-bit FORTH had an accepted method of storing 64-bit, so-called ‘double-width’ numbers, in two positions on the stack, with the most-significant word ‘on top’, and the less-significant word in second position from the ‘top’. Correspondingly, ‘normal’ 32-bit FORTH possesses special operators that can either perform full, double-width arithmetic, which treats two consecutive stack-positions as defining a single number, or mixed-width arithmetic, in which two single-width numbers can lead to a double-width product, or by which a double-width number can be divided by a single-width, to arrive at a single-width quotient, and optionally, also to arrive at a single-width modulus / remainder.

This is a fashion in which 32-bit CPUs have generally been able to perform 64-bit arithmetic, partially. And if the reader is not familiar with how this is accessible under FORTH, I can suggest This External Article as a source of reference.

But, if the reader has installed the 64-bit GNU FORTH, which is also just called ‘gforth’ under Linux, then I should call to his attention, that now, each stack-position is capable of holding a 64-bit number, and that all the operators on those numbers are possible, which would otherwise be available for 32-bit numbers, with no special naming.

The following is a small text-session-clip, that illustrates how this works:

 


dirk@Klystron:~$ gforth
Gforth 0.7.2, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
1 cells . 8  ok
hex  ok
$0123456789ABCDEF $100000000 /mod .s <2> 89ABCDEF 1234567  ok
$20 lshift + .s <1> 123456789ABCDEF  ok
dup  ok
m* .s <2> -235A1DF76F0D5ADF 14B66DC33F6AC  ok
d. 14B66DC33F6ACDCA5E20890F2A521  ok
bye 
dirk@Klystron:~$ 


 

So the ‘/mod’, the ‘lshift’ and the ‘+’ operators are spelled exactly as they would have been for 32-bit FORTH, but operate on potential 64-bit numbers. ‘gforth’ still preserves the double-width operators with the special naming, but in this case, double-width actually means 128-bit ! Its implementation of the standard Fetch operator, which is still named ‘@’, now fetches a 64-bit value from RAM. And I have already documented this slight incompatibility in This Earlier Posting.

If we can assume that our source-code is to be compiled on 64-bit FORTH, we can just perform 64-bit operations on single stack-positions, at will.

It should also be noted that in FORTH comments and stack-traces, the topmost stack-position is written on the right-hand side of the textual list. The apparent negative number above, in the second stack position from the logical top, after ‘ m* .s ‘ , is the result of the most-significant bit of that word being a (1) and not a (0). By convention, in signed integers, this will trigger that a negative number is meant, using two’s complement. And this is still the case, in hexadecimal. But, because this word is the less-significant of the two listed, its most-significant bit will no longer be the most-significant, after it has been combined with the other word, thereby again forming a positive number when printed out as a single 128-bit, signed, integer.

(Edit 07/31/2017 : )

One fact which I have blatantly ignored in my own coding, was that the way in which I chose to separate a single numeric value into two bit-fields – through a modulus-division – is not the most efficient in terms of how many CPU-clock-cycles it consumes. A preferable way to do the same thing, is by using ‘rshift’, and then masking.

The reason for this is the fact that when a CPU is instructed to left-shift or right-shift a binary register-content, doing so takes up about 1 clock-cycle per bit-position shifted. What people may not realize, is that although addition and subtraction can easily be performed in one step by logic-circuits, multiplication and division may not be, assuming a generic, general-purpose CPU. To multiply two 64-bit numbers, actually means to perform 64 additions optionally, each depending on the value of one bit. And to divide a 64-bit number by another, actually means to perform 64 subtractions optionally, each depending on the outcome of a comparison. Maybe for 32-bit or 16-bit registers, we don’t care. But by the time we’re using 64-bit numbers, it penalizes our CPU-load twice as much.

Continue reading 64-bit FORTH

How the JACK Sound Daemon is capable of running at 192kHz

Most of my Linux-computers have as their sound-server ““. But specifically on my laptop named ‘‘, I have set up the to be able to run as an alternative, yet not to be running by default. I have performed experiments on that laptop, to confirm that I can launch this sound-server, using a GUI named ‘‘, but have also had to make modifications to how this GUI executes commands from the user, so that its start-up pauses the , which has been able to resume successfully after I was done using . Without such a detail, the attempt should not be made.

One fact which I can see in , is that is capable of running at 192kHz, even though it has not interrogated any of the available devices, about their real capabilities are.

The reason this is possible is the fact that individual sound devices are just clients to that daemon, including any number of devices that act as sound-sources, rather than acting as sinks, i.e. that act as inputs rather than as one output.

I also own a USB-Sound-Device named the ‘‘, which is mainly intended for use in sound capture, but which also has outputs intended for monitoring purposes.

If I was to run at 192kHz, then one simple consequence of that would be, that zero actual sound-devices would remain compatible with it. As to how cleanly an attempt to connect to an incompatible device exits, giving error messages or crashes, I have not tested, because when I tested the , I took into account the real limit of that device at 96kHz.

Similarly, the runs with 32-bit linear precision by default. In this case, when we enable devices to act as clients, which are only capable of 24-bit sample-depth, which is common, the mismatch is safely ignored. already sees to it, that the last 8 bits of precision get ignored.

Now, I could be cautious and worry, that because of errors in the Linux drivers, those last 8 bits somehow get mapped to a control register as an error. But then the simple way to test for that, was simply to send some 32-bit sound through JACK, to this output device. What I found when testing this, is that the basic operation of the was not disturbed, even though my hearing was not good enough, to tell me when I had my Sennheisers on, whether in fact 24-bit precision was still working. I was mainly testing, that trying to send a 32-bit value, does not disrupt the actual operation.

Continue reading How the JACK Sound Daemon is capable of running at 192kHz

Chrome For Linux Upgrade Glitch Fixed By Google

One of the facts which I had observed about the Google Chrome browser version, which is meant for Linux, was that Google no longer provides a 32-bit version of its binaries. In keeping with this, Google has also removed the section in its code repository, which would make a 32-bit version available. Hence, I can only be subscribing to the 64-bit upgrades. Yet, my Linux computer ‘Phoenix’ has its package manager set up, to query a repository for both the 64-bit and the 32-bit versions of any package by default, and then to download and install the packages which are relevant.

In this earlier posting, I observed how this can lead to an error message when running ‘apt-get update‘. What I had done, was to make minor configuration changes like so, which I had needed to re-apply, after every upgrade to Chrome.

Well Google has caught up with the scenario which I was describing. As of their latest upgrade, their own ‘cron.daily‘ symlink will properly put the following source into ‘/etc/apt/sources.list.d/google-chrome.list‘ :


deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main

You may note, that the script from Google now includes the ‘[arch=amd64]‘ parameter, which means that I won’t have to make any manual adjustments to this configuration detail of my machine, every time the Chrome browser receives an upgrade.

Thank you, Google!

Dirk