#include #include #include #include #include using namespace std; float *table; const int values_per_degree = 100000; const int tablesize = values_per_degree * 360; void partial_init(size_t start, size_t stop){ for(unsigned int i = start; i < stop; i++){ float degrees = (float)i / values_per_degree; table[i] = sinf(degrees / (180.0 / M_PI)); } } void fastmath_init(){ // Make the actual table table = new float[tablesize]; int threads = 8; vector threadlist; for(int i = 0; i < threads; i++){ threadlist.push_back(new thread(partial_init, i * (tablesize/8), (i+1) * (tablesize/8))); } for(auto t : threadlist) t->join(); // Wait for all those threads to finish! } float fast_sin(float degrees){ while(degrees < 0) degrees += 360.0; return table[(int)(degrees * values_per_degree) % tablesize]; // table lookup goes here } float fast_cos(float degrees){ return fast_sin(degrees + 90); } void fastmath_cleanup(){ delete [] table; } /* Minimal bar-making function * bar is a null-terminated string of 100 asterisks * Since it's null-terminated, a pointer partway through the string will be a * pointer to a valid shorter null-terminated string of asterisks. Kinda like * if you want to watch a half-hour movie, you could start watching a 2-hour * movie starting 1.5 hours in, and in half an hour you'd reach the end. */ const char* mkbar(int len){ static const char *bar = "***************************************************************************************************"; return bar + (100 - len); } int main(){ /* Uncomment this next call once you have fastmath_init working */ fastmath_init(); /* * Uncomment this next loop once you have fast_sin working * If it's working right, you should see a sin wave printed from this line */ for(int i = -360; i < 720; i += 10) cout << mkbar(fast_sin(i) * 30 + 30) << " " << fast_sin(i) << endl; /* This is a speed benchmark */ float *testvals = new float[10000]; for(int i = 0; i < 10000; i++) testvals[i] = (random() % 360000) / 1000.0; /* using namespace chrono; system_clock::time_point start = system_clock::now(); float r; for(int i = 0; i < 100000; i++) for(int j = 0; j < 10000; j++) r += fast_sin(testvals[j] + i); // Replace sinf with fast_sin once it works system_clock::time_point end = system_clock::now(); duration time_taken = end - start; cout << "Time taken: " << time_taken.count() << " seconds" << endl; cout << r << endl; delete [] testvals; */ /* Uncomment this next loop once you've written fast_cos, to compare values with cosf */ for(int i = 0; i < 360; i+= 15){ cout << i << " " << cosf(i / (180.0 / M_PI)) << "\t" << fast_cos(i) << endl; } /* Uncomment this next call once you have fastmath_cleanup working */ fastmath_cleanup(); return 0; }