Difference between revisions of "Main Page"

From Dirks Personal WiKi
m
m (Section Headers)
Line 10: Line 10:
 
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]
 
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]
   
  +
== Some Experimentation with MediaWiKi ==
  +
  +
=== Basics ===
 
<span id="Eq 1">Eq 1:</span> {{spaces|2|emsp}} <math>y=\pm\sqrt{1-x^{2}}</math> {{spaces|2|emsp}} (Equation for circle.)
 
<span id="Eq 1">Eq 1:</span> {{spaces|2|emsp}} <math>y=\pm\sqrt{1-x^{2}}</math> {{spaces|2|emsp}} (Equation for circle.)
   
Line 19: Line 22:
 
* [[#Eq 2|Eq 2]]
 
* [[#Eq 2|Eq 2]]
 
* [[#Eq 3|Eq 3]]
 
* [[#Eq 3|Eq 3]]
  +
* [[#Replacement Code for C++2017|Some Working C++]]
 
</tab>
 
</tab>
  +
  +
=== Inter-WiKi Links ===
   
 
The following is a hypothetical exercise...
 
The following is a hypothetical exercise...
Line 28: Line 34:
   
 
----
 
----
  +
  +
== A Real Coding Issue ==
   
 
The following is some (C++) code which has been suggested, to compute the reciprocal square root [[wikipedia:Fast inverse square root|using a trick]]. It may not be helpful, because this code requires that the language implementation can already perform multiplication and subtraction in [[wikipedia:Double precision|double-precision, floating-point]] representation, as well as to access such numbers as though they were integers. The fact that so-called 'doubles' have 11 most significant bits that state their power of 2 means that for most purposes, this sort of [[wikipedia:Type punning|type-punning]] computes their logarithm very quickly, which, in turn, is useful to produce a first approximation of their reciprocal square root, of the form...
 
The following is some (C++) code which has been suggested, to compute the reciprocal square root [[wikipedia:Fast inverse square root|using a trick]]. It may not be helpful, because this code requires that the language implementation can already perform multiplication and subtraction in [[wikipedia:Double precision|double-precision, floating-point]] representation, as well as to access such numbers as though they were integers. The fact that so-called 'doubles' have 11 most significant bits that state their power of 2 means that for most purposes, this sort of [[wikipedia:Type punning|type-punning]] computes their logarithm very quickly, which, in turn, is useful to produce a first approximation of their reciprocal square root, of the form...
Line 38: Line 46:
   
 
What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works...
 
What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works...
  +
  +
=== What No Longer Works ===
   
 
<syntaxhighlight lang="cpp" highlight="3">
 
<syntaxhighlight lang="cpp" highlight="3">
Line 54: Line 64:
 
</syntaxhighlight>
 
</syntaxhighlight>
   
  +
=== Replacement Code for C++2017 ===
----
 
   
 
The rest of the (working) computation applies [[wikipedia:Newton's Method|Newton's Method]] 4 extra times, resulting in precision which reaches the limit of the double-precision floating-point format.
 
The rest of the (working) computation applies [[wikipedia:Newton's Method|Newton's Method]] 4 extra times, resulting in precision which reaches the limit of the double-precision floating-point format.
Line 90: Line 100:
   
 
</syntaxhighlight>
 
</syntaxhighlight>
  +
  +
=== Reason Such Code Was Invented ===
   
 
Of course, the original hack had as context that in early 3D games, texture maps were also associated with normal-maps that only had 8 bits of (signed) precision per coordinate (fetched as R, G and B components of a specially-prepared texture image, at 8 bits per channel), so that even 32-bit, single-precision floating point numbers were overkill for certain parts of the rendering. And so, a real speed improvement can be achieved over ''accurate'' computations, by reducing the number of passes of Newton's Method, to 2 or even 1. In this case, precision is truly not equivalent to accuracy.
 
Of course, the original hack had as context that in early 3D games, texture maps were also associated with normal-maps that only had 8 bits of (signed) precision per coordinate (fetched as R, G and B components of a specially-prepared texture image, at 8 bits per channel), so that even 32-bit, single-precision floating point numbers were overkill for certain parts of the rendering. And so, a real speed improvement can be achieved over ''accurate'' computations, by reducing the number of passes of Newton's Method, to 2 or even 1. In this case, precision is truly not equivalent to accuracy.

Revision as of 09:53, 31 August 2024

This is a personal MediaWiki.

The User's Guide will explain how to use the WiKi software, to Dirk.

Getting started

Some Experimentation with MediaWiKi

Basics

Eq 1:    [math]\displaystyle{ y=\pm\sqrt{1-x^{2}} }[/math]    (Equation for circle.)

Drop-Down Menu

Inter-WiKi Links

The following is a hypothetical exercise...

A cartoon centipede reads books and types on a laptop.
The Wikipede edits wikipedia:Myriapoda.

This example is supposed to show how thumbnails can be made to display by default, as well as how inter-WiKi links work.


A Real Coding Issue

The following is some (C++) code which has been suggested, to compute the reciprocal square root using a trick. It may not be helpful, because this code requires that the language implementation can already perform multiplication and subtraction in double-precision, floating-point representation, as well as to access such numbers as though they were integers. The fact that so-called 'doubles' have 11 most significant bits that state their power of 2 means that for most purposes, this sort of type-punning computes their logarithm very quickly, which, in turn, is useful to produce a first approximation of their reciprocal square root, of the form...

Eq 2:    [math]\displaystyle{ \ln\left(\frac{1}{\sqrt{x}}\right)-\frac{1}{2}\ln\left(x\right) }[/math]

Why, exactly, the constants are used as starting values, from which half the punned value of (x) is to be subtracted, is not clear to most people, including This Author. This may have more to do with the binary floating-point format than with the square root of (x). Yet, the fact that Matthew Robertson was able to derive the double-precision version suggests that he knows. What's being computed more closely resembles...

Eq 3:    [math]\displaystyle{ C-\frac{1}{2}\ln\left(x\right) }[/math]

What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works...

What No Longer Works

float64_t Q_failed_pun(const float64_t number) {
    uint64_t *temp1 = (uint64_t *) &number;
    uint64_t temp2 = 0x5FE6EB50C7B537A9 - (*temp1 >> 1);
    float64_t *out = (float64_t *) temp2;
    return *out;
}

Because of how efficiently the compilers optimize the code, line 3 becomes equivalent to...

    uint64_t temp2 = 0x5FE6EB50C7B537A9 - ((uint64_t) number / 2);

Replacement Code for C++2017

The rest of the (working) computation applies Newton's Method 4 extra times, resulting in precision which reaches the limit of the double-precision floating-point format.

/*  Fast Inverse Square Root, using Matthew Robertson's
 * Magic Number for double-precision floating-point.
 * 
 * Implemented August 2, 2024
 * by Dirk Mittler
 * 
 */

#include <cstring>
#include <cstdint>

typedef double float64_t;

float64_t Q_rsqrt(const float64_t number) noexcept {
	const float64_t threehalfs = 1.5;
	const float64_t halfnum = 0.5 * number;
	uint64_t temp;
	float64_t y;
	static_assert(sizeof(uint64_t) == sizeof(number),
					"`double` has a weird size.");
	memcpy(&temp, &number, sizeof(float64_t));
//	temp = 0x5f3759df - (temp >> 1);	// Original 32-bit fr Quake III
	temp = 0x5FE6EB50C7B537A9 - (temp >> 1);	// Matthew Robertson's
	memcpy(&y, &temp, sizeof(float64_t));
	y *= (threehalfs - (halfnum * y * y));
	y *= (threehalfs - (halfnum * y * y));
	y *= (threehalfs - (halfnum * y * y));
	return y * (threehalfs - (halfnum * y * y));
}

Reason Such Code Was Invented

Of course, the original hack had as context that in early 3D games, texture maps were also associated with normal-maps that only had 8 bits of (signed) precision per coordinate (fetched as R, G and B components of a specially-prepared texture image, at 8 bits per channel), so that even 32-bit, single-precision floating point numbers were overkill for certain parts of the rendering. And so, a real speed improvement can be achieved over accurate computations, by reducing the number of passes of Newton's Method, to 2 or even 1. In this case, precision is truly not equivalent to accuracy.