ååã誤差éä¼æ¬æ³ãlibfixmathã©ã¤ãã©ãªã使ã£ã¦åºå®å°æ°ç¹åããããããéã«åºå®å°æ°ç¹åã«ããæ§è½ãä½ä¸ãã¦ãã¾ã£ã¦ããã ãã¯ãã©ã¤ãã©ãªã«ãããªã¼ããããã§ã¯ãªãã ãããã¨ãããã¨ã§ãæ§è½è§£æãè¡ããã¨ã«ããã
Google Perfã«ããPerformance解æ
ã¾ããMNISTãã¬ã¼ãã³ã°ããã°ã©ã ãGoogle Performance Toolsã使ã£ã¦æ§è½è¦å 解æãè¡ã£ããdoubleçãfloatçãfix16_tçã§æ¯è¼ããCallee Mapãä½æããã
- fix16_t ç
- floatç
- doubleç
fix16_t
çã§ã¯ãã©ã¤ãã©ãªã¨ãã¦å¼ã³åºãã¦ãããfix16_mul
, fix16_add
ãçµæ§ãªæéãè¦ãã¦ãããããã¯ã©ã®ãããªå®è£
ã«ãªã£ã¦ãããã¨ããã¨ãã½ã¼ã¹ã³ã¼ããèªãã°ãããã
#ifndef FIXMATH_NO_OVERFLOW fix16_t fix16_add(fix16_t a, fix16_t b) { // Use unsigned integers because overflow with signed integers is // an undefined operation (http://www.airs.com/blog/archives/120). uint32_t _a = a, _b = b; uint32_t sum = _a + _b; // Overflow can only happen if sign of a == sign of b, and then // it causes sign of sum != sign of a. if (!((_a ^ _b) & 0x80000000) && ((_a ^ sum) & 0x80000000)) return fix16_overflow; return sum; }
ããã§æ°ãä»ããã®ã ããFIXMATH_NO_OVERFLOW
ã¨ãããã¯ããå®ç¾©ããã¦ããããã®ãã¯ããå®ç¾©ãããã¨ã«ãã£ã¦ãªã¼ãããã¼ãæ¤åºããªãã³ã¼ããåºåãããã¨ãã§ãããå
·ä½çã«ã¯fix16.h
ã«å®ç¾©ããã¦ãã以ä¸ã使ç¨ãããã
#ifdef FIXMATH_NO_OVERFLOW static inline fix16_t fix16_add(fix16_t inArg0, fix16_t inArg1) { return (inArg0 + inArg1); } static inline fix16_t fix16_sub(fix16_t inArg0, fix16_t inArg1) { return (inArg0 - inArg1); } #else
ã³ãã©ã使ã£ã¦ãã³ã³ãã¤ã«ãã¦æ§è½æ¸¬å®ãã¦ã¿ãããã¨ãããã詳細ãªæ§è½æ¸¬å®ãé¢åãªã®ã§ãtime
ã使ã£ã¦æ¸¬å®ããã
ã¾ãã¾ãããããªãã«éããªã£ã¦ããããããã§ãdouble, floatçã«ã¯è¿½ãä»ãã¦ããªããä½æ ããã
- FIXMATH_NO_OVERFLOW ç
real 0m23.020s user 0m22.412s sys 0m0.544s
- FIXMATH_NO_OVERFLOW ç¡ãç
real 0m48.244s user 0m48.044s sys 0m0.124s
| double ç | 0m6.659s | | floatç | 0m9.847s | | fix16 w/o NO_OVERFLOW | 0m48.244s | | fix16 w/ NO_OVERFLOW | 0m23.020s |
ãã¨ãã¨doubleçããã¼ã¹ã«ä½ã£ãã¨ãããã¨ããããfloatã®æ¹ãé ãã¨ããã®ã¯ï¼ï¼ï¼ã ããfix16_tçã¯è¶³å ã«ãåãã§ããªãã
Raspberry-Pi3ã§å®è¡
å ¨ãé¢ä¿ãªããRaspberry-Pi3ã§MNISTããã°ã©ã ãã³ã³ãã¤ã«ãã¦å®è¡ãããå ¨ãåé¡ãªãlibfixmath, train_twolayrnetãã³ã³ãã¤ã«ã§ãããå®è¡çµæãæ³å®éãã ã
RISC-Vã§å®è¡ (ã³ã³ãã¤ã«)
TARGETãRISC-Vã«å¤æ´ããã¾ãã¯ã³ã³ãã¤ã«ãã¦ã¿ãã
- libfixmath: Makefileãå°ãã ãå¤æ´ãã
TARGET=riscv64-unknown-elf-gcc
ãè¨å®ãã¦ã³ã³ãã¤ã«ã
diff --git a/libfixmath/Makefile b/libfixmath/Makefile index b284590..2acfc04 100644 --- a/libfixmath/Makefile +++ b/libfixmath/Makefile @@ -3,15 +3,18 @@ PROJECT = libfixmath LIB = SRC = . INC = +# DEF = -DFIXMATH_NO_OVERFLOW #Compiler settings -CPP = gcc -CC = gcc -AS = gcc -LD = gcc -AR = ar -CPP_FLAGS = -O2 $(INC) -Wall -Wextra -c -CC_FLAGS = -O2 $(INC) -Wall -Wextra -c +TARGET = + +CPP = $(TARGET)gcc +CC = $(TARGET)gcc +AS = $(TARGET)gcc +LD = $(TARGET)gcc +AR = $(TARGET)ar +CPP_FLAGS = -O2 $(INC) $(DEF) -Wall -Wextra -c +CC_FLAGS = -O2 $(INC) $(DEF) -Wall -Wextra -c
$ make TARGET=riscv64-unknown-elf- riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fix16_str.o fix16_str.c riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fract32.o fract32.c riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o uint32.o uint32.c riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fix16_exp.o fix16_exp.c riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fix16_sqrt.o fix16_sqrt.c riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fix16_trig.o fix16_trig.c fix16_trig.c: In function 'fix16_tan': fix16_trig.c:116:9: warning: implicit declaration of function 'fix16_sdiv' [-Wimplicit-function-declaration] return fix16_sdiv(fix16_sin(inAngle), fix16_cos(inAngle)); ^~~~~~~~~~ riscv64-unknown-elf-gcc -O2 -DFIXMATH_NO_OVERFLOW -Wall -Wextra -c -o fix16.o fix16.c riscv64-unknown-elf-ar rcs libfixmath.a ./fix16_str.o ./fract32.o ./uint32.o ./fix16_exp.o ./fix16_sqrt.o ./fix16_trig.o ./fix16.o
train_twolayernetã®æ¹ããCC=riscv64-unknown-elf
ãè¨å®ãã¦ã³ã³ãã¤ã«ããã
$ make CC=riscv64-unknown-elf-gcc train_twolayernet_fix16 riscv64-unknown-elf-gcc -std=gnu11 -O3 -g -DFIXMATH_NO_OVERFLOW train_twolayernet_fix16.c -o train_twolayernet_fix16 -L./libfixmath/libfixmath -I./libfixmath/libfixmath -lfixmath -lm