Changes in / [fe8aa21:d00d581]
- Files:
-
- 13 added
- 23 deleted
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/code/CondCatch.java
rfe8aa21 rd00d581 6 6 static boolean should_catch = false; 7 7 8 static void throw_exception() throws EmptyException { 9 throw new EmptyException(); 10 } 11 12 static void cond_catch() throws EmptyException { 13 try { 14 throw_exception(); 15 } catch (EmptyException exc) { 16 if (!should_catch) { 17 throw exc; 18 } 19 } 20 } 21 8 22 private static long loop(int times) { 9 23 long startTime = System.nanoTime(); 10 24 for (int count = 0 ; count < times ; ++count) { 11 25 try { 12 try { 13 throw new EmptyException(); 14 } catch (EmptyException exc) { 15 if (!should_catch) { 16 throw exc; 17 } 18 } 26 cond_catch(); 19 27 } catch (EmptyException exc) { 20 28 // ... … … 38 46 39 47 long time = loop(times); 40 System.out. format("Run-Time (s): %.1f%n", time / 1_000_000_000.);48 System.out.println("Run-Time (ns): " + time); 41 49 } 42 50 } -
doc/theses/andrew_beach_MMath/code/ThrowEmpty.java
rfe8aa21 rd00d581 39 39 40 40 long time = loop(times, total_frames); 41 System.out. format("Run-Time (s): %.1f%n", time / 1_000_000_000.);41 System.out.println("Run-Time (ns): " + time); 42 42 } 43 43 } -
doc/theses/andrew_beach_MMath/code/ThrowFinally.java
rfe8aa21 rd00d581 44 44 45 45 long time = loop(times, total_frames); 46 System.out. format("Run-Time (s): %.1f%n", time / 1_000_000_000.);46 System.out.println("Run-Time (ns): " + time); 47 47 } 48 48 } -
doc/theses/andrew_beach_MMath/code/ThrowOther.java
rfe8aa21 rd00d581 52 52 53 53 long time = loop(times, total_frames); 54 System.out. format("Run-Time (s): %.1f%n", time / 1_000_000_000.);54 System.out.println("Run-Time (ns): " + time); 55 55 } 56 56 } -
doc/theses/andrew_beach_MMath/code/cond-catch.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.h fa> // strto5 #include <stdlib.h> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 bool should_catch = false; 12 13 void throw_exception() { 14 throw (empty_exception){&empty_vt}; 15 } 16 17 void cond_catch() { 18 try { 19 throw_exception(); 20 } catch (empty_exception * exc ; should_catch) { 21 asm volatile ("# catch block (conditional)"); 22 } 23 } 11 24 12 25 int main(int argc, char * argv[]) { 13 26 unsigned int times = 1; 14 27 if (1 < argc) { 15 times = strto (argv[1], 0p, 10);28 times = strtol(argv[1], 0p, 10); 16 29 } 17 30 if (2 < argc) { 18 should_catch = (unsigned int)strto(argv[2], 0p, 2);31 should_catch = strtol(argv[2], 0p, 10); 19 32 } 20 33 … … 22 35 for (unsigned int count = 0 ; count < times ; ++count) { 23 36 try { 24 throw (empty_exception){&empty_vt}; 25 } catch (empty_exception * exc ; should_catch) { 26 asm volatile ("# catch block (conditional)"); 37 cond_catch(); 27 38 } catch (empty_exception * exc) { 28 39 asm volatile ("# catch block (unconditional)"); … … 30 41 } 31 42 Time end_time = timeHiRes(); 32 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);43 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 33 44 } -
doc/theses/andrew_beach_MMath/code/cond-catch.cpp
rfe8aa21 rd00d581 4 4 #include <exception> 5 5 #include <iostream> 6 #include <iomanip>7 6 8 using namespace std;9 7 using namespace std::chrono; 10 8 … … 12 10 13 11 bool should_catch = false; 12 13 void throw_exception() { 14 throw EmptyException(); 15 } 16 17 void cond_catch() { 18 try { 19 throw_exception(); 20 } catch (EmptyException & exc) { 21 if (!should_catch) { 22 throw; 23 } 24 asm volatile ("# catch block (conditional)"); 25 } 26 } 14 27 15 28 int main(int argc, char * argv[]) { … … 25 38 for (unsigned int count = 0 ; count < times ; ++count) { 26 39 try { 27 try { 28 throw EmptyException(); 29 } catch (EmptyException & exc) { 30 if (!should_catch) { 31 throw; 32 } 33 asm volatile ("# catch block (conditional)"); 34 } 40 cond_catch(); 35 41 } catch (EmptyException &) { 36 42 asm volatile ("# catch block (unconditional)"); … … 39 45 time_point<steady_clock> end_time = steady_clock::now(); 40 46 nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time); 41 cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. <<endl;47 std::cout << "Run-Time (ns): " << duration.count() << std::endl; 42 48 } -
doc/theses/andrew_beach_MMath/code/cond-fixup.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 bool should_catch = false; 12 13 void throw_exception() { 14 throwResume (empty_exception){&empty_vt}; 15 } 16 17 void cond_catch() { 18 try { 19 throw_exception(); 20 } catchResume (empty_exception * exc ; should_catch) { 21 asm volatile ("# fixup block (conditional)"); 22 } 23 } 11 24 12 25 int main(int argc, char * argv[]) { 13 26 unsigned int times = 1; 14 27 if (1 < argc) { 15 times = strto (argv[1], 0p, 10);28 times = strtol(argv[1], 0p, 10); 16 29 } 17 30 if (2 < argc) { 18 should_catch = (unsigned int)strto(argv[2], 0p, 2);31 should_catch = strtol(argv[2], 0p, 10); 19 32 } 20 33 … … 22 35 for (unsigned int count = 0 ; count < times ; ++count) { 23 36 try { 24 throwResume (empty_exception){&empty_vt}; 25 } catchResume (empty_exception * exc ; should_catch) { 26 asm volatile ("# fixup block (conditional)"); 37 cond_catch(); 27 38 } catchResume (empty_exception * exc) { 28 39 asm volatile ("# fixup block (unconditional)"); … … 30 41 } 31 42 Time end_time = timeHiRes(); 32 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);43 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 33 44 } -
doc/theses/andrew_beach_MMath/code/resume-detor.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 struct WithDestructor {}; … … 16 17 void unwind_destructor(unsigned int frames) { 17 18 if (frames) { 19 18 20 WithDestructor object; 19 21 unwind_destructor(frames - 1); … … 27 29 unsigned int total_frames = 1; 28 30 if (1 < argc) { 29 times = strto (argv[1], 0p, 10);31 times = strtol(argv[1], 0p, 10); 30 32 } 31 33 if (2 < argc) { 32 total_frames = strto (argv[2], 0p, 10);34 total_frames = strtol(argv[2], 0p, 10); 33 35 } 34 36 … … 42 44 } 43 45 Time end_time = timeHiRes(); 44 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);46 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 45 47 } -
doc/theses/andrew_beach_MMath/code/resume-empty.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 9 8 10 void nounwind_empty(unsigned int frames) { 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 10 11 void unwind_empty(unsigned int frames) { 11 12 if (frames) { 12 nounwind_empty(frames - 1);13 unwind_empty(frames - 1); 13 14 } else { 14 15 throwResume (empty_exception){&empty_vt}; … … 20 21 unsigned int total_frames = 1; 21 22 if (1 < argc) { 22 times = strto (argv[1], 0p, 10);23 times = strtol(argv[1], 0p, 10); 23 24 } 24 25 if (2 < argc) { 25 total_frames = strto (argv[2], 0p, 10);26 total_frames = strtol(argv[2], 0p, 10); 26 27 } 27 28 28 29 Time start_time = timeHiRes(); 29 for ( unsignedint count = 0 ; count < times ; ++count) {30 for (int count = 0 ; count < times ; ++count) { 30 31 try { 31 nounwind_empty(total_frames);32 unwind_empty(total_frames); 32 33 } catchResume (empty_exception *) { 33 34 asm volatile ("# fixup block"); … … 35 36 } 36 37 Time end_time = timeHiRes(); 37 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);38 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 38 39 } -
doc/theses/andrew_beach_MMath/code/resume-finally.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 void unwind_finally(unsigned int frames) { … … 24 25 unsigned int total_frames = 1; 25 26 if (1 < argc) { 26 times = strto (argv[1], 0p, 10);27 times = strtol(argv[1], 0p, 10); 27 28 } 28 29 if (2 < argc) { 29 total_frames = strto (argv[2], 0p, 10);30 total_frames = strtol(argv[2], 0p, 10); 30 31 } 31 32 … … 39 40 } 40 41 Time end_time = timeHiRes(); 41 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);42 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 42 43 } -
doc/theses/andrew_beach_MMath/code/resume-other.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 9 exception not_raised_exception; 7 EHM_EXCEPTION(empty_exception)(); 10 8 11 void nounwind_other(unsigned int frames) { 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 10 11 EHM_EXCEPTION(not_raised_exception)(); 12 13 void unwind_other(unsigned int frames) { 12 14 if (frames) { 13 15 try { 14 nounwind_other(frames - 1);16 unwind_other(frames - 1); 15 17 } catchResume (not_raised_exception *) { 16 18 asm volatile ("# fixup block (stack)"); … … 25 27 unsigned int total_frames = 1; 26 28 if (1 < argc) { 27 times = strto (argv[1], 0p, 10);29 times = strtol(argv[1], 0p, 10); 28 30 } 29 31 if (2 < argc) { 30 total_frames = strto (argv[2], 0p, 10);32 total_frames = strtol(argv[2], 0p, 10); 31 33 } 32 34 … … 34 36 for (int count = 0 ; count < times ; ++count) { 35 37 try { 36 nounwind_other(total_frames);38 unwind_other(total_frames); 37 39 } catchResume (empty_exception *) { 38 40 asm volatile ("# fixup block (base)"); … … 40 42 } 41 43 Time end_time = timeHiRes(); 42 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);44 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 43 45 } -
doc/theses/andrew_beach_MMath/code/run.sh
rfe8aa21 rd00d581 1 1 #!/usr/bin/env bash 2 2 3 readonly ALL_TESTS=( raise-{empty,detor,finally,other} try-{catch,finally} cond-match-{all,none} \4 raise-{fixup-empty,fixup-other})3 readonly ALL_TESTS=(cond-match-{all,none} cross-{catch,finally} \ 4 raise-{detor,empty,finally,other}) 5 5 6 6 gen-file-name() ( … … 18 18 ) 19 19 20 #readonly N=${1:-5} 21 readonly N=${1:-1} 20 readonly N=${1:-5} 22 21 readonly OUT_FILE=$(gen-file-name ${2:-run-%-$N}) 23 22 -
doc/theses/andrew_beach_MMath/code/test.sh
rfe8aa21 rd00d581 4 4 # test.sh LANGUAGE TEST 5 5 # Run the TEST in LANGUAGE. 6 # test.sh -a7 # Build all tests.8 6 # test.sh -b SOURCE_FILE... 9 7 # Build a test from SOURCE_FILE(s). 10 # test.sh -c11 # Clean all executables.12 8 # test.sh -v LANGUAGE TEST FILE 13 9 # View the result from TEST in LANGUAGE stored in FILE. 14 10 15 readonly ITERS_1M=1000000 # 1 000 000, one million 16 readonly ITERS_10M=10000000 # 10 000 000, ten million 17 readonly ITERS_100M=100000000 # 100 000 000, hundred million 18 readonly ITERS_1000M=1000000000 # 1 000 000 000, billion 11 readonly ITERATIONS=1000000 # 1 000 000, one million 19 12 readonly STACK_HEIGHT=100 20 13 … … 31 24 *.cfa) 32 25 # Requires a symbolic link. 33 mmake "${1%.cfa}" "$1" cfa -DNDEBUG -nodebug -O3 "$1" -o "${1%.cfa}"26 mmake "${1%.cfa}" "$1" ./cfa -DNDEBUG -nodebug -O3 "$1" -o "${1%.cfa}" 34 27 ;; 35 28 *.cpp) 36 mmake "${1%.cpp}-cpp" "$1" g++ -10-DNDEBUG -O3 "$1" -o "${1%.cpp}-cpp"29 mmake "${1%.cpp}-cpp" "$1" g++ -DNDEBUG -O3 "$1" -o "${1%.cpp}-cpp" 37 30 ;; 38 31 *.java) … … 46 39 ) 47 40 48 if [ "-a" = "$1" ]; then # build all 49 for file in *.cfa *.cpp *.java; do 50 build $file 51 done 52 exit 0 53 elif [ "-b" = "$1" ]; then # build given 41 if [ "-b" = "$1" ]; then 54 42 for file in "${@:2}"; do 55 43 build $file 56 44 done 57 45 exit 0 58 elif [ "-c" = "$1" ]; then # clean all59 rm -f `basename -s ".cfa" -a *.cfa`60 rm -f `basename -s ".cpp" -a *.cpp`61 rm -f *-cpp62 rm -f *.class63 exit 064 46 elif [ "-v" = "$1" -a 4 = "$#" ]; then 65 66 67 47 TEST_LANG="$2" 48 TEST_CASE="$3" 49 VIEW_FILE="$4" 68 50 elif [ 2 -eq "$#" ]; then 69 51 TEST_LANG="$1" … … 81 63 82 64 case "$TEST_CASE" in 83 raise-empty) 84 CFAT="./throw-empty $ITERS_1M $STACK_HEIGHT" 85 # see resume-fixup-empty-r CFAR="./resume-empty $ITERS_1M $STACK_HEIGHT" 86 CPP="./throw-empty-cpp $ITERS_1M $STACK_HEIGHT" 87 JAVA="java ThrowEmpty $ITERS_1M $STACK_HEIGHT" 88 PYTHON="./throw-empty.py $ITERS_1M $STACK_HEIGHT" 65 cond-match-all) 66 CFAT="./cond-catch $ITERATIONS 1" 67 CFAR="./cond-fixup $ITERATIONS 1" 68 CPP="./cond-catch-cpp $ITERATIONS 1" 69 JAVA="java CondCatch $ITERATIONS 1" 70 PYTHON="./cond_catch.py $ITERATIONS 1" 71 ;; 72 cond-match-none) 73 CFAT="./cond-catch $ITERATIONS 0" 74 CFAR="./cond-fixup $ITERATIONS 0" 75 CPP="./cond-catch-cpp $ITERATIONS 0" 76 JAVA="java CondCatch $ITERATIONS 0" 77 PYTHON="./cond_catch.py $ITERATIONS 0" 78 ;; 79 cross-catch) 80 CFAT="./cross-catch $ITERATIONS" 81 CFAR="./cross-resume $ITERATIONS" 82 CPP="./cross-catch-cpp $ITERATIONS" 83 JAVA="java CrossCatch $ITERATIONS" 84 PYTHON="./cross_catch.py $ITERATIONS" 85 ;; 86 cross-finally) 87 CFAT="./cross-finally $ITERATIONS" 88 CFAR=unsupported 89 CPP=unsupported 90 JAVA="java CrossFinally $ITERATIONS" 91 PYTHON="./cross_finally.py $ITERATIONS" 89 92 ;; 90 93 raise-detor) 91 CFAT="./throw-detor $ITER S_1M$STACK_HEIGHT"92 # N/A CFAR="./resume-detor $ITERS_1M$STACK_HEIGHT"93 CPP="./throw-detor-cpp $ITER S_1M$STACK_HEIGHT"94 CFAT="./throw-detor $ITERATIONS $STACK_HEIGHT" 95 CFAR="./resume-detor $ITERATIONS $STACK_HEIGHT" 96 CPP="./throw-detor-cpp $ITERATIONS $STACK_HEIGHT" 94 97 JAVA=unsupported 95 98 PYTHON=unsupported 96 99 ;; 100 raise-empty) 101 CFAT="./throw-empty $ITERATIONS $STACK_HEIGHT" 102 CFAR="./resume-empty $ITERATIONS $STACK_HEIGHT" 103 CPP="./throw-empty-cpp $ITERATIONS $STACK_HEIGHT" 104 JAVA="java ThrowEmpty $ITERATIONS $STACK_HEIGHT" 105 PYTHON="./throw_empty.py $ITERATIONS $STACK_HEIGHT" 106 ;; 97 107 raise-finally) 98 CFAT="./throw-finally $ITER S_1M$STACK_HEIGHT"99 # N/A CFAR="./resume-finally $ITERS_1M$STACK_HEIGHT"108 CFAT="./throw-finally $ITERATIONS $STACK_HEIGHT" 109 CFAR="./resume-finally $ITERATIONS $STACK_HEIGHT" 100 110 CPP=unsupported 101 JAVA="java ThrowFinally $ITER S_1M$STACK_HEIGHT"102 PYTHON="./throw -finally.py $ITERS_1M$STACK_HEIGHT"111 JAVA="java ThrowFinally $ITERATIONS $STACK_HEIGHT" 112 PYTHON="./throw_finally.py $ITERATIONS $STACK_HEIGHT" 103 113 ;; 104 114 raise-other) 105 CFAT="./throw-other $ITERS_1M $STACK_HEIGHT" 106 # N/A CFAR="./resume-other $ITERS_1M $STACK_HEIGHT" 107 CPP="./throw-other-cpp $ITERS_1M $STACK_HEIGHT" 108 JAVA="java ThrowOther $ITERS_1M $STACK_HEIGHT" 109 PYTHON="./throw-other.py $ITERS_1M $STACK_HEIGHT" 110 ;; 111 try-catch) 112 CFAT="./try-catch $ITERS_1000M" 113 CFAR="./try-resume $ITERS_1000M" 114 CPP="./try-catch-cpp $ITERS_1000M" 115 JAVA="java TryCatch $ITERS_1000M" 116 PYTHON="./try-catch.py $ITERS_1000M" 117 ;; 118 try-finally) 119 CFAT="./try-finally $ITERS_1000M" 120 CFAR=unsupported 121 CPP=unsupported 122 JAVA="java TryFinally $ITERS_1000M" 123 PYTHON="./try-finally.py $ITERS_1000M" 124 ;; 125 cond-match-all) 126 CFAT="./cond-catch $ITERS_10M 1" 127 CFAR="./cond-fixup $ITERS_10M 1" 128 CPP="./cond-catch-cpp $ITERS_10M 1" 129 JAVA="java CondCatch $ITERS_10M 1" 130 PYTHON="./cond-catch.py $ITERS_10M 1" 131 ;; 132 cond-match-none) 133 CFAT="./cond-catch $ITERS_10M 0" 134 CFAR="./cond-fixup $ITERS_10M 0" 135 CPP="./cond-catch-cpp $ITERS_10M 0" 136 JAVA="java CondCatch $ITERS_10M 0" 137 PYTHON="./cond-catch.py $ITERS_10M 0" 138 ;; 139 raise-fixup-empty) 140 CFAT="./resume-fixup-empty-f $ITERS_10M $STACK_HEIGHT" 141 CFAR="./resume-fixup-empty-r $ITERS_10M $STACK_HEIGHT" 142 CPP="./resume-fixup-empty-cpp $ITERS_10M $STACK_HEIGHT" 143 JAVA="java ResumeFixupEmpty $ITERS_10M $STACK_HEIGHT" 144 PYTHON="./resume-fixup-empty.py $ITERS_10M $STACK_HEIGHT" 145 ;; 146 raise-fixup-other) 147 CFAT="./resume-fixup-other-f $ITERS_10M $STACK_HEIGHT" 148 CFAR="./resume-fixup-other-r $ITERS_10M $STACK_HEIGHT" 149 CPP="./resume-fixup-other-cpp $ITERS_10M $STACK_HEIGHT" 150 JAVA="java ResumeFixupOther $ITERS_10M $STACK_HEIGHT" 151 PYTHON="./resume-fixup-other.py $ITERS_10M $STACK_HEIGHT" 115 CFAT="./throw-other $ITERATIONS $STACK_HEIGHT" 116 CFAR="./resume-other $ITERATIONS $STACK_HEIGHT" 117 CPP="./throw-other-cpp $ITERATIONS $STACK_HEIGHT" 118 JAVA="java ThrowOther $ITERATIONS $STACK_HEIGHT" 119 PYTHON="./throw_other.py $ITERATIONS $STACK_HEIGHT" 152 120 ;; 153 121 *) … … 158 126 159 127 case "$TEST_LANG" in 160 161 162 163 164 165 166 167 128 cfa-t) CALL="$CFAT";; 129 cfa-r) CALL="$CFAR";; 130 cpp) CALL="$CPP";; 131 java) CALL="$JAVA";; 132 python) CALL="$PYTHON";; 133 *) 134 echo "No such language: $TEST_LANG" >&2 135 exit 2 168 136 ;; 169 137 esac … … 172 140 173 141 if [ -n "$VIEW_FILE" ]; then 174 175 142 grep -A 1 -B 0 "$CALL" "$VIEW_FILE" | sed -n -e 's!Run-Time (ns): !!;T;p' 143 exit 176 144 fi 177 145 -
doc/theses/andrew_beach_MMath/code/throw-detor.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 struct WithDestructor {}; … … 27 28 unsigned int total_frames = 1; 28 29 if (1 < argc) { 29 times = strto (argv[1], 0p, 10);30 times = strtol(argv[1], 0p, 10); 30 31 } 31 32 if (2 < argc) { 32 total_frames = strto (argv[2], 0p, 10);33 total_frames = strtol(argv[2], 0p, 10); 33 34 } 34 35 … … 42 43 } 43 44 Time end_time = timeHiRes(); 44 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);45 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 45 46 } -
doc/theses/andrew_beach_MMath/code/throw-detor.cpp
rfe8aa21 rd00d581 4 4 #include <exception> 5 5 #include <iostream> 6 #include <iomanip>7 6 8 using namespace std;9 7 using namespace std::chrono; 10 8 … … 46 44 time_point<steady_clock> end_time = steady_clock::now(); 47 45 nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time); 48 cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. <<endl;46 std::cout << "Run-Time (ns): " << duration.count() << std::endl; 49 47 } -
doc/theses/andrew_beach_MMath/code/throw-empty.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 8 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 9 10 10 11 void unwind_empty(unsigned int frames) { … … 20 21 unsigned int total_frames = 1; 21 22 if (1 < argc) { 22 times = strto (argv[1], 0p, 10);23 times = strtol(argv[1], 0p, 10); 23 24 } 24 25 if (2 < argc) { 25 total_frames = strto (argv[2], 0p, 10);26 total_frames = strtol(argv[2], 0p, 10); 26 27 } 27 28 … … 35 36 } 36 37 Time end_time = timeHiRes(); 37 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);38 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 38 39 } -
doc/theses/andrew_beach_MMath/code/throw-empty.cpp
rfe8aa21 rd00d581 4 4 #include <exception> 5 5 #include <iostream> 6 #include <iomanip>7 6 8 using namespace std;9 7 using namespace std::chrono; 10 8 … … 39 37 time_point<steady_clock> end_time = steady_clock::now(); 40 38 nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time); 41 cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. <<endl;39 std::cout << "Run-Time (ns): " << duration.count() << std::endl; 42 40 } -
doc/theses/andrew_beach_MMath/code/throw-finally.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 7 EHM_EXCEPTION(empty_exception)(); 9 8 10 unsigned int frames; // use global because of gcc thunk problem 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 11 10 12 void unwind_finally(unsigned int dummy) {11 void unwind_finally(unsigned int frames) { 13 12 if (frames) { 14 frames -= 1;15 13 try { 16 unwind_finally( 42);14 unwind_finally(frames - 1); 17 15 } finally { 18 16 asm volatile ("# finally block"); 19 17 } 20 18 } else { 21 dummy = 42;22 19 throw (empty_exception){&empty_vt}; 23 20 } … … 28 25 unsigned int total_frames = 1; 29 26 if (1 < argc) { 30 times = strto (argv[1], 0p, 10);27 times = strtol(argv[1], 0p, 10); 31 28 } 32 29 if (2 < argc) { 33 total_frames = strto (argv[2], 0p, 10);30 total_frames = strtol(argv[2], 0p, 10); 34 31 } 35 frames = total_frames;36 32 37 33 Time start_time = timeHiRes(); 38 34 for (int count = 0 ; count < times ; ++count) { 39 35 try { 40 unwind_finally( 42);36 unwind_finally(total_frames); 41 37 } catch (empty_exception *) { 42 38 asm volatile ("# catch block"); … … 44 40 } 45 41 Time end_time = timeHiRes(); 46 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);42 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 47 43 } -
doc/theses/andrew_beach_MMath/code/throw-other.cfa
rfe8aa21 rd00d581 3 3 #include <exception.hfa> 4 4 #include <fstream.hfa> 5 #include <stdlib.hfa> // strto5 #include <stdlib.hfa> 6 6 7 exception empty_exception; 8 vtable(empty_exception) empty_vt; 9 exception not_raised_exception; 7 EHM_EXCEPTION(empty_exception)(); 10 8 11 unsigned int frames; // use global because of gcc thunk problem 9 EHM_VIRTUAL_TABLE(empty_exception, empty_vt); 12 10 13 void unwind_other(unsigned int dummy) { 11 EHM_EXCEPTION(not_raised_exception)(); 12 13 void unwind_other(unsigned int frames) { 14 14 if (frames) { 15 frames -= 1;16 15 try { 17 unwind_other( 42);16 unwind_other(frames - 1); 18 17 } catch (not_raised_exception *) { 19 18 asm volatile ("# catch block (stack)"); 20 19 } 21 20 } else { 22 dummy = 42;23 21 throw (empty_exception){&empty_vt}; 24 22 } … … 29 27 unsigned int total_frames = 1; 30 28 if (1 < argc) { 31 times = strto (argv[1], 0p, 10);29 times = strtol(argv[1], 0p, 10); 32 30 } 33 31 if (2 < argc) { 34 total_frames = strto (argv[2], 0p, 10);32 total_frames = strtol(argv[2], 0p, 10); 35 33 } 36 frames = total_frames;37 34 38 35 Time start_time = timeHiRes(); 39 36 for (int count = 0 ; count < times ; ++count) { 40 37 try { 41 unwind_other( 42);38 unwind_other(total_frames); 42 39 } catch (empty_exception *) { 43 40 asm volatile ("# catch block (base)"); … … 45 42 } 46 43 Time end_time = timeHiRes(); 47 sout | "Run-Time ( s): " | wd(0,1, (end_time - start_time)`ns / 1_000_000_000.);44 sout | "Run-Time (ns): " | (end_time - start_time)`ns; 48 45 } -
doc/theses/andrew_beach_MMath/code/throw-other.cpp
rfe8aa21 rd00d581 4 4 #include <exception> 5 5 #include <iostream> 6 #include <iomanip>7 6 8 using namespace std;9 7 using namespace std::chrono; 10 8 … … 45 43 time_point<steady_clock> end_time = steady_clock::now(); 46 44 nanoseconds duration = duration_cast<nanoseconds>(end_time - start_time); 47 cout << "Run-Time (s): " << fixed << setprecision(1) << duration.count() / 1'000'000'000. <<endl;45 std::cout << "Run-Time (ns): " << duration.count() << std::endl; 48 46 } -
doc/theses/andrew_beach_MMath/performance.tex
rfe8aa21 rd00d581 3 3 4 4 Performance is of secondary importance for most of this project. 5 Instead, the focus was to get the features working. The only performance5 Instead, the focus is to get the features working. The only performance 6 6 requirement is to ensure the tests for correctness run in a reasonable 7 amount of time. Hence, a few basic performance tests were performed to 8 check this requirement. 7 amount of time. 9 8 10 9 \section{Test Set-Up} … … 15 14 C++ is the most comparable language because both it and \CFA use the same 16 15 framework, libunwind. 17 In fact, the comparison is almost entirely a quality of implementation .18 Specifically,\CFA's EHM has had significantly less time to be optimized and16 In fact, the comparison is almost entirely a quality of implementation 17 comparison: \CFA's EHM has had significantly less time to be optimized and 19 18 does not generate its own assembly. It does have a slight advantage in that 20 19 there are some features it handles directly instead of through utility functions, 21 but otherwise \Cpp should havea significant advantage.22 23 Java is a popular language with similar termination semantics, but24 it is implemented in a very different environment, a virtual machine with20 but otherwise \Cpp has a significant advantage. 21 22 Java is another very popular language with similar termination semantics. 23 It is implemented in a very different environment, a virtual machine with 25 24 garbage collection. 26 25 It also implements the @finally@ clause on @try@ blocks allowing for a direct 27 26 feature-to-feature comparison. 28 As with \Cpp, Java's implementation is mature, optimiz ed27 As with \Cpp, Java's implementation is mature, optimizations 29 28 and has extra features. 30 29 31 Python is used as an alternative comparison because of the \CFA EHM's30 Python is used as an alternative point of comparison because of the \CFA EHM's 32 31 current performance goals, which is not to be prohibitively slow while the 33 32 features are designed and examined. Python has similar performance goals for … … 37 36 resumption exceptions. Even the older programming languages with resumption 38 37 seem to be notable only for having resumption. 39 So instead, resumption is compared to its simulation in other programming 40 languages using fixup functions that are explicitly passed for correction or 41 logging purposes. 42 % So instead, resumption is compared to a less similar but much more familiar 43 %feature, termination exceptions. 38 So instead, resumption is compared to a less similar but much more familiar 39 feature, termination exceptions. 44 40 45 41 All tests are run inside a main loop that repeatedly performs a test. 46 42 This approach avoids start-up or tear-down time from 47 43 affecting the timing results. 48 Each test is run a N times (configurable from the command line).49 The Java tests runs the main loop1000 times before50 beginning t heactual test to ``warm-up" the JVM.44 Each test is run a million times. 45 The Java versions of the test run this loop an extra 1000 times before 46 beginning to actual test to ``warm-up" the JVM. 51 47 52 48 Timing is done internally, with time measured immediately before and … … 70 66 71 67 The tests are compiled with gcc-10 for \CFA and g++-10 for \Cpp. Java is 72 compiled with version 11.0.11. Python with version3.8. The tests were run on:68 compiled with 11.0.11. Python with 3.8. The tests were run on: 73 69 \begin{itemize}[nosep] 74 70 \item … … 77 73 AMD 6380 Abu Dhabi 16-core 4$\times$socket \lstinline{@} 2.5 GHz running Linux v5.11.0-25 78 74 \end{itemize} 79 Two kinds of hardware architecture allows discriminating any implementation and80 architectural effects.81 82 75 83 76 % We don't use catch-alls but if we did: … … 91 84 92 85 \paragraph{Raise and Handle} 93 Th is group measures the cost of a try statement when exceptions are raised and94 the stack is unwound (termination) or not unwound (resumption). Each test has 95 has a repeating function likethe following96 \begin{ lstlisting}[language=CFA,{moredelim=**[is][\color{red}]{@}{@}}]86 The first group measures the cost of a try statement when exceptions are raised 87 and \emph{the stack is unwound}. Each test has has a repeating function like 88 the following 89 \begin{cfa} 97 90 void unwind_empty(unsigned int frames) { 98 91 if (frames) { 99 @unwind_empty(frames - 1);@ // AUGMENTED IN OTHER EXPERIMENTS92 unwind_empty(frames - 1); 100 93 } else throw (empty_exception){&empty_vt}; 101 94 } 102 \end{ lstlisting}103 which is called N times, where each call recurses to a depth of R (configurable from the command line), an95 \end{cfa} 96 which is called M times, where each call recurses to a depth of N, an 104 97 exception is raised, the stack is a unwound, and the exception caught. 105 98 \begin{itemize}[nosep] 106 99 \item Empty: 107 For termination, this test measures the cost of raising (stack walking) an 108 exception through empty stack frames from the bottom of the recursion to an 109 empty handler, and unwinding the stack. (see above code) 110 111 \medskip 112 For resumption, this test measures the same raising cost but does not unwind 113 the stack. For languages without resumption, a fixup function is to the bottom 114 of the recursion and called to simulate a fixup operation at that point. 115 \begin{cfa} 116 void nounwind_fixup(unsigned int frames, void (*raised_rtn)(int &)) { 117 if (frames) { 118 nounwind_fixup(frames - 1, raised_rtn); 119 } else { 120 int fixup = 17; 121 raised_rtn(fixup); 122 } 123 } 124 \end{cfa} 125 where the passed fixup function is: 126 \begin{cfa} 127 void raised(int & fixup) { 128 fixup = 42; 129 } 130 \end{cfa} 131 For comparison, a \CFA version passing a function is also included. 100 This test measures the cost of raising (stack walking) an exception through empty 101 empty stack frames to an empty handler. (see above) 132 102 \item Destructor: 133 This test measures the cost of raising an exception through non-empty frames, 134 where each frame has an object requiring destruction, from the bottom of the 135 recursion to an empty handler. Hence, there are N destructor calls during 136 unwinding. 137 138 \medskip 139 This test is not meaningful for resumption because the stack is only unwound as 140 the recursion returns. 141 \begin{cfa} 103 104 This test measures the cost of raising an exception through non-empty frames 105 where each frame has an object requiring destruction, to an empty 106 handler. Hence, there are N destructor calls during unwinding. 107 \begin{cfa} 108 if (frames) { 142 109 WithDestructor object; 143 unwind_ destructor(frames - 1);110 unwind_empty(frames - 1); 144 111 \end{cfa} 145 112 \item Finally: 146 113 This test measures the cost of establishing a try block with an empty finally 147 clause on the front side of the recursion and running the empty finally clauses 148 during stack unwinding from the bottom of the recursion to an empty handler. 149 \begin{cfa} 114 clause on the front side of the recursion and running the empty finally clause 115 on the back side of the recursion during stack unwinding. 116 \begin{cfa} 117 if (frames) { 150 118 try { 151 119 unwind_finally(frames - 1); 152 120 } finally {} 153 121 \end{cfa} 154 155 \medskip156 This test is not meaningful for resumption because the stack is only unwound as157 the recursion returns.158 122 \item Other Handler: 159 For termination, this test is like the finally test but the try block has a 160 catch clause for an exception that is not raised, so catch matching is executed 161 during stack unwinding but the match never successes until the catch at the 162 bottom of the recursion. 163 \begin{cfa} 123 This test is like the finally test but the try block has a catch clause for an 124 exception that is not raised, so catch matching is executed during stack 125 unwinding but the match never successes until the catch at the bottom of the 126 stack. 127 \begin{cfa} 128 if (frames) { 164 129 try { 165 130 unwind_other(frames - 1); 166 131 } catch (not_raised_exception *) {} 167 132 \end{cfa} 168 169 \medskip 170 For resumption, this test measures the same raising cost but does not unwind 171 the stack. For languages without resumption, the same fixup function is passed 172 and called. 173 \end{itemize} 174 175 \paragraph{Try/Handle/Finally Statement} 176 This group measures just the cost of executing a try statement so 133 \end{itemize} 134 135 \paragraph{Cross Try Statement} 136 The next group measures just the cost of executing a try statement so 177 137 \emph{there is no stack unwinding}. Hence, the program main loops N times 178 138 around: … … 183 143 \begin{itemize}[nosep] 184 144 \item Handler: 185 The try statement has a handler (catch/resume).145 The try statement has a handler. 186 146 \item Finally: 187 The try statement hasa finally clause.147 The try statement replaces the handler with a finally clause. 188 148 \end{itemize} 189 149 190 150 \paragraph{Conditional Matching} 191 This group measures the cost of conditional matching.151 This final group measures the cost of conditional matching. 192 152 Only \CFA implements the language level conditional match, 193 the other languages m imic with an ``unconditional" match (it still194 checks the exception's type) and conditional re-raise if it is not suppose153 the other languages must mimic with an ``unconditional" match (it still 154 checks the exception's type) and conditional re-raise if it was not supposed 195 155 to handle that exception. 196 156 \begin{center} … … 221 181 \end{itemize} 222 182 223 \medskip224 \noindent225 All omitted test code for other languages is functionally identical to the \CFA226 tests or simulated, and available online~\cite{CforallExceptionBenchmarks}.227 228 183 %\section{Cost in Size} 229 184 %Using exceptions also has a cost in the size of the executable. … … 237 192 238 193 \section{Results} 239 One result not directly related to \CFA but important to keep in 240 mind is that, for exceptions, the standard intuition about which languages 241 should go faster often does not hold. For example, there are a few cases where Python out-performs 242 \CFA, \Cpp and Java. The most likely explanation is that, since exceptions are 243 rarely considered to be the common case, the more optimized languages 244 make that case expense. In addition, languages with high-level 245 representations have a much easier time scanning the stack as there is less 246 to decode. 247 248 Tables~\ref{t:PerformanceTermination} and~\ref{t:PerformanceResumption} show 249 the test results for termination and resumption, respectively. In cases where 250 a feature is not supported by a language, the test is skipped for that language 251 (marked N/A). For some Java experiments it was impossible to measure certain 252 effects because the JIT corrupted the test (marked N/C). No workaround was 253 possible~\cite{Dice21}. To get experiments in the range of 1--100 seconds, the 254 number of times an experiment is run (N) is varied (N is marked beside each 255 experiment, e.g., 1M $\Rightarrow$ 1 million test iterations). 256 257 An anomaly exists with gcc nested functions used as thunks for implementing 258 much of the \CFA EHM. If a nested-function closure captures local variables in 259 its lexical scope, performance dropped by a factor of 10. Specifically, in try 260 statements of the form: 261 \begin{cfa} 262 try { 263 unwind_other(frames - 1); 264 } catch (not_raised_exception *) {} 265 \end{cfa} 266 the try block is hoisted into a nested function and the variable @frames@ is 267 the local parameter to the recursive function, which triggers the anomaly. The 268 workaround is to remove the recursion parameter and make it a global variable 269 that is explicitly decremented outside of the try block (marked with a ``*''): 270 \begin{cfa} 271 frames -= 1; 272 try { 273 unwind_other(); 274 } catch (not_raised_exception *) {} 275 \end{cfa} 276 To make comparisons fair, a dummy parameter is added and the dummy value passed 277 in the recursion. Note, nested functions in gcc are rarely used (if not 278 completely unknown) and must follow the C calling convention, unlike \Cpp 279 lambdas, so it is not surprising if there are performance issues efficiently 280 capturing closures. 281 282 % Similarly, if a test does not change between resumption 283 % and termination in \CFA, then only one test is written and the result 284 % was put into the termination column. 194 In cases where a feature is not supported by a language the test is skipped 195 for that language. 196 \PAB{Report all values. 197 198 Similarly, if a test does not change between resumption 199 and termination in \CFA, then only one test is written and the result 200 was put into the termination column. 201 } 285 202 286 203 % Raw Data: … … 318 235 % Match None & 0.0 & 0.0 & 9476060146 & 0.0 & 0.0 \\ 319 236 237 \begin{tabular}{|l|c c c c c|} 238 \hline 239 & \CFA (Terminate) & \CFA (Resume) & \Cpp & Java & Python \\ 240 \hline 241 Raise Empty & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 242 Raise D'tor & 0.0 & 0.0 & 0.0 & N/A & N/A \\ 243 Raise Finally & 0.0 & 0.0 & N/A & 0.0 & 0.0 \\ 244 Raise Other & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 245 Cross Handler & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 246 Cross Finally & 0.0 & N/A & N/A & 0.0 & 0.0 \\ 247 Match All & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 248 Match None & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 249 \hline 250 \end{tabular} 251 320 252 % run-plg7a-a.sat 321 253 % --------------- … … 352 284 % Match None & 0.0 & 0.0 & 7829059869 & 0.0 & 0.0 \\ 353 285 354 \begin{table} 355 \centering 356 \caption{Performance Results Termination (sec)} 357 \label{t:PerformanceTermination} 358 \begin{tabular}{|r|*{2}{|r r r r|}} 359 \hline 360 & \multicolumn{4}{c||}{AMD} & \multicolumn{4}{c|}{ARM} \\ 361 \cline{2-9} 362 N\hspace{8pt} & \multicolumn{1}{c}{\CFA} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c||}{Python} & 363 \multicolumn{1}{c}{\CFA} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c|}{Python} \\ 364 \hline 365 Throw Empty (1M) & 3.4 & 2.8 & 18.3 & 23.4 & 3.7 & 3.2 & 15.5 & 14.8 \\ 366 Throw D'tor (1M) & 48.4 & 23.6 & N/A & N/A & 64.2 & 29.0 & N/A & N/A \\ 367 Throw Finally (1M) & 3.4* & N/A & 17.9 & 29.0 & 4.1* & N/A & 15.6 & 19.0 \\ 368 Throw Other (1M) & 3.6* & 23.2 & 18.2 & 32.7 & 4.0* & 24.5 & 15.5 & 21.4 \\ 369 Try/Catch (100M) & 6.0 & 0.9 & N/C & 37.4 & 10.0 & 0.8 & N/C & 32.2 \\ 370 Try/Finally (100M) & 0.9 & N/A & N/C & 44.1 & 0.8 & N/A & N/C & 37.3 \\ 371 Match All (10M) & 32.9 & 20.7 & 13.4 & 4.9 & 36.2 & 24.5 & 12.0 & 3.1 \\ 372 Match None (10M) & 32.7 & 50.3 & 11.0 & 5.1 & 36.3 & 71.9 & 12.3 & 4.2 \\ 286 % PLG7A (in seconds) 287 \begin{tabular}{|l|c c c c c|} 288 \hline 289 & \CFA (Terminate) & \CFA (Resume) & \Cpp & Java & Python \\ 290 \hline 291 Raise Empty & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 292 Raise D'tor & 0.0 & 0.0 & 0.0 & N/A & N/A \\ 293 Raise Finally & 0.0 & 0.0 & N/A & 0.0 & 0.0 \\ 294 Raise Other & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 295 Cross Handler & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 296 Cross Finally & 0.0 & N/A & N/A & 0.0 & 0.0 \\ 297 Match All & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 298 Match None & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\ 373 299 \hline 374 300 \end{tabular} 375 \end{table} 376 377 \begin{table} 378 \centering 379 \small 380 \caption{Performance Results Resumption (sec)} 381 \label{t:PerformanceResumption} 382 \setlength{\tabcolsep}{5pt} 383 \begin{tabular}{|r|*{2}{|r r r r|}} 384 \hline 385 & \multicolumn{4}{c||}{AMD} & \multicolumn{4}{c|}{ARM} \\ 386 \cline{2-9} 387 N\hspace{8pt} & \multicolumn{1}{c}{\CFA (R/F)} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c||}{Python} & 388 \multicolumn{1}{c}{\CFA (R/F)} & \multicolumn{1}{c}{\Cpp} & \multicolumn{1}{c}{Java} & \multicolumn{1}{c|}{Python} \\ 389 \hline 390 Resume Empty (10M) & 3.8/3.5 & 14.7 & 2.3 & 176.1 & 0.3/0.1 & 8.9 & 1.2 & 119.9 \\ 391 Resume Other (10M) & 4.0*/0.1* & 21.9 & 6.2 & 381.0 & 0.3*/0.1* & 13.2 & 5.0 & 290.7 \\ 392 Try/Resume (100M) & 8.8 & N/A & N/A & N/A & 12.3 & N/A & N/A & N/A \\ 393 Match All (10M) & 0.3 & N/A & N/A & N/A & 0.3 & N/A & N/A & N/A \\ 394 Match None (10M) & 0.3 & N/A & N/A & N/A & 0.4 & N/A & N/A & N/A \\ 395 \hline 396 \end{tabular} 397 \end{table} 398 399 As stated, the performance tests are not attempting to compare exception 400 handling across languages. The only performance requirement is to ensure the 401 \CFA EHM implementation runs in a reasonable amount of time, given its 402 constraints. In general, the \CFA implement did very well. Each of the tests is 403 analysed. 404 \begin{description} 405 \item[Throw/Resume Empty] 406 For termination, \CFA is close to \Cpp, where other languages have a higher cost. 407 408 For resumption, \CFA is better than the fixup simulations in the other languages, except Java. 409 The \CFA results on the ARM computer for both resumption and function simulation are particularly low; 410 I have no explanation for this anomaly, except the optimizer has managed to remove part of the experiment. 411 Python has a high cost for passing the lambda during the recursion. 412 413 \item[Throw D'tor] 414 For termination, \CFA is twice the cost of \Cpp. 415 The higher cost for \CFA must be related to how destructors are handled. 416 417 \item[Throw Finally] 418 \CFA is better than the other languages with a @finally@ clause, which is the 419 same for termination and resumption. 420 421 \item[Throw/Resume Other] 422 For termination, \CFA is better than the other languages. 423 424 For resumption, \CFA is equal to or better the other languages. 425 Again, the \CFA results on the ARM computer for both resumption and function simulation are particularly low. 426 Python has a high cost for passing the lambda during the recursion. 427 428 \item[Try/Catch/Resume] 429 For termination, installing a try statement is more expressive than \Cpp 430 because the try components are hoisted into local functions. At runtime, these 431 functions are than passed to libunwind functions to set up the try statement. 432 \Cpp zero-cost try-entry accounts for its performance advantage. 433 434 For resumption, there are similar costs to termination to set up the try 435 statement but libunwind is not used. 436 437 \item[Try/Finally] 438 Setting up a try finally is less expensive in \CFA than setting up handlers, 439 and is significantly less than other languages. 440 441 \item[Throw/Resume Match All] 442 For termination, \CFA is close to the other language simulations. 443 444 For resumption, the stack unwinding is much faster because it does not use 445 libunwind. Instead resumption is just traversing a linked list with each node 446 being the next stack frame with the try block. 447 448 \item[Throw/Resume Match None] 449 The same results as for Match All. 450 \end{description} 451 452 \begin{comment} 453 This observation means that while \CFA does not actually keep up with Python in 454 every case, it is usually no worse than roughly half the speed of \Cpp. This 455 performance is good enough for the prototyping purposes of the project. 301 302 One result not directly related to \CFA but important to keep in 303 mind is that, for exceptions, the standard intuition about which languages 304 should go faster often does not hold. For example, there are cases where Python out-performs 305 \Cpp and Java. The most likely explanation is that, since exceptions are 306 rarely considered to be the common case, the more optimized languages 307 make that case expense. In addition, languages with high-level 308 representations have a much easier time scanning the stack as there is less 309 to decode. 310 311 This observation means that while \CFA does not actually keep up with Python in every 312 case, it is usually no worse than roughly half the speed of \Cpp. This performance is good 313 enough for the prototyping purposes of the project. 456 314 457 315 The test case where \CFA falls short is Raise Other, the case where the 458 316 stack is unwound including a bunch of non-matching handlers. 459 317 This slowdown seems to come from missing optimizations. 318 319 Importantly, there is a huge slowdown in \Cpp's results bringing that brings 320 \CFA's performance back in that roughly half speed area. However many other 321 \CFA benchmarks increase their run-time by a similar amount falling far 322 behind their \Cpp counter-parts. 460 323 461 324 This suggests that the performance issue in Raise Other is just an … … 501 364 The difference in relative performance does show that there are savings to 502 365 be made by performing the check without catching the exception. 503 \end{comment}504 505 506 \begin{comment}507 From: Dave Dice <dave.dice@oracle.com>508 To: "Peter A. Buhr" <pabuhr@uwaterloo.ca>509 Subject: Re: [External] : JIT510 Date: Mon, 16 Aug 2021 01:21:56 +0000511 512 > On 2021-8-15, at 7:14 PM, Peter A. Buhr <pabuhr@uwaterloo.ca> wrote:513 >514 > My student is trying to measure the cost of installing a try block with a515 > finally clause in Java.516 >517 > We tried the random trick (see below). But if the try block is comment out, the518 > results are the same. So the program measures the calls to the random number519 > generator and there is no cost for installing the try block.520 >521 > Maybe there is no cost for a try block with an empty finally, i.e., the try is522 > optimized away from the get-go.523 524 There's quite a bit of optimization magic behind the HotSpot curtains for525 try-finally. (I sound like the proverbial broken record (:>)).526 527 In many cases we can determine that the try block can't throw any exceptions,528 so we can elide all try-finally plumbing. In other cases, we can convert the529 try-finally to normal if-then control flow, in the case where the exception is530 thrown into the same method. This makes exceptions _almost cost-free. If we531 actually need to "physically" rip down stacks, then things get expensive,532 impacting both the throw cost, and inhibiting other useful optimizations at the533 catch point. Such "true" throws are not just expensive, they're _very534 expensive. The extremely aggressive inlining used by the JIT helps, because we535 can convert cases where a heavy rip-down would normally needed back into simple536 control flow.537 538 Other quirks involve the thrown exception object. If it's never accessed then539 we're apply a nice set of optimizations to avoid its construction. If it's540 accessed but never escapes the catch frame (common) then we can also cheat.541 And if we find we're hitting lots of heavy rip-down cases, the JIT will542 consider recompilation - better inlining -- to see if we can merge the throw543 and catch into the same physical frame, and shift to simple branches.544 545 In your example below, System.out.print() can throw, I believe. (I could be546 wrong, but most IO can throw). Native calls that throw will "unwind" normally547 in C++ code until they hit the boundary where they reenter java emitted code,548 at which point the JIT-ed code checks for a potential pending exception. So in549 a sense the throw point is implicitly after the call to the native method, so550 we can usually make those cases efficient.551 552 Also, when we're running in the interpreter and warming up, we'll notice that553 the == 42 case never occurs, and so when we start to JIT the code, we elide the554 call to System.out.print(), replacing it (and anything else which appears in555 that if x == 42 block) with a bit of code we call an "uncommon trap". I'm556 presuming we encounter 42 rarely. So if we ever hit the x == 42 case, control557 hits the trap, which triggers synchronous recompilation of the method, this558 time with the call to System.out.print() and, because of that, we now to adapt559 the new code to handle any traps thrown by print(). This is tricky stuff, as560 we may need to rebuild stack frames to reflect the newly emitted method. And561 we have to construct a weird bit of "thunk" code that allows us to fall back562 directly into the newly emitted "if" block. So there's a large one-time cost563 when we bump into the uncommon trap and recompile, and subsequent execution564 might get slightly slower as the exception could actually be generated, whereas565 before we hit the trap, we knew the exception could never be raised.566 567 Oh, and things also get expensive if we need to actually fill in the stack568 trace associated with the exception object. Walking stacks is hellish.569 570 Quite a bit of effort was put into all this as some of the specjvm benchmarks571 showed significant benefit.572 573 It's hard to get sensible measurements as the JIT is working against you at574 every turn. What's good for the normal user is awful for anybody trying to575 benchmark. Also, all the magic results in fairly noisy and less reproducible576 results.577 578 Regards579 Dave580 581 p.s., I think I've mentioned this before, but throwing in C++ is grim as582 unrelated throws in different threads take common locks, so nothing scales as583 you might expect.584 \end{comment} -
doc/theses/andrew_beach_MMath/uw-ethesis.bib
rfe8aa21 rd00d581 2 2 % For use with BibTeX 3 3 4 @misc{Dice21, 5 author = {Dave Dice}, 6 year = 2021, 7 month = aug, 8 howpublished= {personal communication} 4 @book{goossens.book, 5 author = "Michel Goossens and Frank Mittelbach and 6 Alexander Samarin", 7 title = "The \LaTeX\ Companion", 8 year = "1994", 9 publisher = "Addison-Wesley", 10 address = "Reading, Massachusetts" 9 11 } 10 12 11 @misc{CforallExceptionBenchmarks, 12 contributer = {pabuhr@plg}, 13 key = {Cforall Exception Benchmarks}, 14 author = {{\textsf{C}{$\mathbf{\forall}$} Exception Benchmarks}}, 15 howpublished= {\href{https://github.com/cforall/ExceptionBenchmarks_SPE20}{https://\-github.com/\-cforall/\-ExceptionBenchmarks\_SPE20}}, 13 @book{knuth.book, 14 author = "Donald Knuth", 15 title = "The \TeX book", 16 year = "1986", 17 publisher = "Addison-Wesley", 18 address = "Reading, Massachusetts" 16 19 } 20 21 @book{lamport.book, 22 author = "Leslie Lamport", 23 title = "\LaTeX\ --- A Document Preparation System", 24 edition = "Second", 25 year = "1994", 26 publisher = "Addison-Wesley", 27 address = "Reading, Massachusetts" 28 } -
libcfa/prelude/builtins.c
rfe8aa21 rd00d581 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 14 08:45:54 202113 // Update Count : 1 3312 // Last Modified On : Wed Jul 21 13:31:34 2021 13 // Update Count : 129 14 14 // 15 15 … … 107 107 #endif // __SIZEOF_INT128__ 108 108 109 // for-control index constraints110 // forall( T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); T ?+=?( T &, T ); T ?-=?( T &, T ); int ?<?( T, T ); } )111 // static inline T __for_control_index_constraints__( T t ) { return t; }112 113 109 // exponentiation operator implementation 114 110 -
src/Parser/parser.yy
rfe8aa21 rd00d581 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Aug 8 09:14:44 202113 // Update Count : 503 812 // Last Modified On : Tue Jul 20 22:03:04 2021 13 // Update Count : 5031 14 14 // 15 15 … … 185 185 type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 186 186 } // if 187 // type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) );188 187 return new ForCtrl( 189 188 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
Note: See TracChangeset
for help on using the changeset viewer.