void TestThreadPool() { CDynArray<int> result; { // Empty: ThreadPool pool; pool.Wait(0); printf("Empty pool pass.\n"); } { int N = 8; ThreadPool pool; for (int i = 0; i < N; ++i) { pool.Add(TFunc, (void*)i); } pool.Wait(&result); result.Sort(); for (int i = 0; i < N; ++i) { GLASSERT(result[i] == i); } printf("Basic test pass.\n"); } { for (int pass = 0; pass < 2; ++pass) { int N = 100; ThreadPool pool; for (int i = 0; i < N; ++i) { pool.Add(TFunc, (void*)i); } pool.Wait(&result); result.Sort(); for (int i = 0; i < N; ++i) { GLASSERT(result[i] == i); } printf("Serial stress %d pass.\n", pass); } } { static const int P = 2; ThreadPool pool[P]; int N = 100; for (int i = 0; i < N; ++i) { for (int pass = 0; pass < P; ++pass) { pool[pass].Add(TFunc, (void*)i); } } for (int pass = 0; pass < P; ++pass) { pool[pass].Wait(&result); result.Sort(); for (int i = 0; i < N; ++i) { GLASSERT(result[i] == i); } } printf("Parallel stress pass.\n"); } }
void RayTrace() { const uint32_t kSamples = g_width*g_height; ThreadPool threadPool; const uint32_t kTileSize = 16; const uint32_t kNumJobs = ceil(g_width / float(kTileSize)) * ceil(g_height / float(kTileSize)); vector<RayJob> jobs(kNumJobs); // create camera const Camera camera(TransformMatrix(g_camDir, g_camPos), 45.0f, 0.1f, 10000.0f, g_width, g_height); uint32_t jobIndex = 0; double startTime = GetSeconds(); // create thread jobs for (uint32_t y=0; y < g_height; y += kTileSize) { uint32_t top = y; uint32_t bottom = min(top+kTileSize, g_height); for (uint32_t x=0; x < g_width; x += kTileSize) { RayJob& job = jobs[jobIndex++]; job.m_rect = Rect(x, min(x+kTileSize, g_width), top, bottom); job.m_camera = camera; job.m_scene = g_scene; job.m_samplesPerPixel = 1; job.m_output = &g_pixels[0]; job.m_outputPitch = g_width; threadPool.AddTask(RayTraceThreadFunc, &job); } } threadPool.Run(g_numWorkers); threadPool.Wait(); // print out trace time every 10 frames double endTime = GetSeconds(); /* cout << "Nodes checked: " << g_nodesChecked << endl; cout << "Tris checked: " << g_trisChecked << endl; g_trisChecked = 0; g_nodesChecked = 0; */ ++g_iterations; Colour* presentMem = g_pixels; if (g_mode == ePathTrace) { float s = g_exposure / g_iterations; for (uint32_t i=0; i < g_width*g_height; ++i) { g_filtered[i] = LinearToSrgb(g_pixels[i] * s); } presentMem = g_filtered; } static uint32_t s_counter=0; if (s_counter % 10) { cout << "Trace took: " << (endTime-startTime)*1000.0f << "ms" << " rays/s: " << g_width*g_height/(endTime-startTime) << endl; } ++s_counter; glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glPixelZoom(float(g_windowWidth)/g_width, float(g_windowHeight)/g_height); glDrawPixels(g_width,g_height,GL_RGBA,GL_FLOAT, presentMem); }