Added option to replace sin function with ~384KiB look-up table for fastest and most accurate results.

Added tool to generate sin tables.
Tests indicate that using a lut is still ~2.1% out from sinf so it's very possible that our sin function is more accurate than the libmath sinf function on the computer I'm testing with. In which case the accuracy results are offset by that amount.
This commit is contained in:
flatmush 2011-02-25 15:32:23 +00:00
parent 0ecfa08dc3
commit 0317f964f4
8 changed files with 13028 additions and 16 deletions

48
fixsingen/fixsingen.cbp Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="fixsingen" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="dbg">
<Option output="bin\dbg\fixsingen" prefix_auto="1" extension_auto="1" />
<Option object_output="obj\dbg\" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="rel">
<Option output="bin\rel\fixsingen" prefix_auto="1" extension_auto="1" />
<Option object_output="obj\rel\" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add directory="..\" />
</Compiler>
<Linker>
<Add library="..\libfixmath\libfixmath.a" />
</Linker>
<Unit filename="main.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -0,0 +1,22 @@
# depslib dependency file v1.0
1298645188 source:g:\vrfx\libfixmath\fixsingen\main.c
<stdio.h>
<stdlib.h>
<inttypes.h>
<math.h>
<libfixmath/fixmath.h>
1298453688 g:\vrfx\libfixmath\\libfixmath\fixmath.h
"uint32.h"
"fract32.h"
"fix16.h"
1298453688 g:\vrfx\libfixmath\\libfixmath\uint32.h
<stdint.h>
1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h
<stdint.h>
1298634082 g:\vrfx\libfixmath\\libfixmath\fix16.h
<stdint.h>

35
fixsingen/main.c Normal file
View File

@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <math.h>
#include <libfixmath/fixmath.h>
int main(int argc, char** argv) {
FILE* fp = fopen("fix16_trig_sin_lut.h", "wb");
if(fp == NULL) {
fprintf(stderr, "Error: Unable to open file for writing.\n");
return EXIT_FAILURE;
}
fprintf(fp, "#ifndef __fix16_trig_sin_lut_h__\n");
fprintf(fp, "#define __fix16_trig_sin_lut_h__\n");
fprintf(fp, "\n");
fprintf(fp, "static fix16_t _fix16_sin_lut[%"PRIi32"] = {", (fix16_pi >> 1));
uintptr_t i;
for(i = 0; i < (fix16_pi >> 1); i++) {
if((i & 7) == 0)
fprintf(fp, "\n\t");
fix16_t fix16_sin_lut = fix16_from_dbl(sin(fix16_to_dbl(i)));
fprintf(fp, "%"PRIi32", ", fix16_sin_lut);
}
fprintf(fp, "\n\t};\n");
fprintf(fp, "\n");
fprintf(fp, "#endif\n");
fclose(fp);
return EXIT_SUCCESS;
}

View File

@ -1,5 +1,5 @@
# depslib dependency file v1.0
1298635002 source:g:\vrfx\libfixmath\fixtest\main.c
1298636296 source:g:\vrfx\libfixmath\fixtest\main.c
<stdio.h>
<stdlib.h>
<math.h>

View File

@ -13,15 +13,20 @@
//#define flt_func expf
//#define flt_func_str "expf"
#define fix_func fix16_atan
#define fix_func_str "fix16_atan"
#define flt_func atanf
#define flt_func_str "atanf"
//#define fix_func fix16_atan
//#define fix_func_str "fix16_atan"
//#define flt_func atanf
//#define flt_func_str "atanf"
//#define fix_func fix16_sin
//#define fix_func_str "fix16_sin"
//#define flt_func sinf
//#define flt_func_str "sinf"
#define fix_func fix16_sin
#define fix_func_str "fix16_sin"
#define flt_func sinf
#define flt_func_str "sinf"
//#define fix_func fix16_sqrt
//#define fix_func_str "fix16_sqrt"
//#define flt_func sqrtf
//#define flt_func_str "sqrtf"
@ -32,7 +37,7 @@ int main(int argc, char** argv) {
uintptr_t args = (1 << 8);
uintptr_t iter = (1 << 8);
uintptr_t pass = (1 << 6);
uintptr_t pass = (1 << 8);
uintptr_t i;
srand(time(NULL));
@ -73,8 +78,8 @@ int main(int argc, char** argv) {
fix_duration += (fix_end - fix_start);
}
printf("% 16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", flt_func_str, flt_duration, HICLOCKS_PER_SEC);
printf("% 16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", fix_func_str, fix_duration, HICLOCKS_PER_SEC);
printf("%16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", flt_func_str, flt_duration, HICLOCKS_PER_SEC);
printf("%16s: %08"PRIuHICLOCK" @ %"PRIu32"Hz\n", fix_func_str, fix_duration, HICLOCKS_PER_SEC);
printf(" Difference: %08"PRIiHICLOCK" (% 3.2f%%)\n", (flt_duration - fix_duration), ((fix_duration * 100.0) / flt_duration));
printf(" Error: %f%%\n", ((fix16_to_dbl(fix_error) * 100.0) / (args * pass)));

View File

@ -1,10 +1,13 @@
#include "fix16.h"
#ifndef FIXMATH_NO_CACHE
#if defined(FIXMATH_SIN_LUT)
#include "fix16_trig_sin_lut.h"
#elif !defined(FIXMATH_NO_CACHE)
static fix16_t _fix16_sin_cache_index[4096] = { 0 };
static fix16_t _fix16_sin_cache_value[4096] = { 0 };
#endif
#ifndef FIXMATH_NO_CACHE
static fix16_t _fix16_atan_cache_index[2][4096] = { { 0 }, { 0 } };
static fix16_t _fix16_atan_cache_value[4096] = { 0 };
#endif
@ -13,6 +16,23 @@ static fix16_t _fix16_atan_cache_value[4096] = { 0 };
fix16_t fix16_sin(fix16_t inAngle) {
fix16_t tempAngle = inAngle % (fix16_pi << 1);
#ifdef FIXMATH_SIN_LUT
if(tempAngle < 0)
tempAngle += (fix16_pi << 1);
fix16_t tempOut;
if(tempAngle >= fix16_pi) {
tempAngle -= fix16_pi;
if(tempAngle >= (fix16_pi >> 1))
tempAngle = fix16_pi - tempAngle;
tempOut = -_fix16_sin_lut[tempAngle];
} else {
if(tempAngle >= (fix16_pi >> 1))
tempAngle = fix16_pi - tempAngle;
tempOut = _fix16_sin_lut[tempAngle];
}
#else
if(tempAngle > fix16_pi)
tempAngle -= (fix16_pi << 1);
else if(tempAngle < -fix16_pi)
@ -26,7 +46,6 @@ fix16_t fix16_sin(fix16_t inAngle) {
fix16_t tempAngleSq = fix16_mul(tempAngle, tempAngle);
#ifndef FIXMATH_FAST_SIN // Most accurate version, accurate to ~2.1%
fix16_t tempOut = tempAngle;
tempAngle = fix16_mul(tempAngle, tempAngleSq);
@ -86,6 +105,7 @@ fix16_t fix16_sin(fix16_t inAngle) {
_fix16_sin_cache_index[tempIndex] = inAngle;
_fix16_sin_cache_value[tempIndex] = tempOut;
#endif
#endif
return tempOut;
}

File diff suppressed because it is too large Load Diff

View File

@ -36,11 +36,18 @@
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-DFIXMATH_NO_CACHE" />
<Add option="-DFIXMATH_SIN_LUT" />
</Compiler>
<Unit filename="Makefile" />
<Unit filename="fix16.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="fix16.h" />
<Unit filename="fix16_exp.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="fix16_sqrt.c">
<Option compilerVar="CC" />
</Unit>