std::pair<int, std::string> find_optimal_alphabet( std::vector<std::string> const& words, int const timeout) { std::mt19937 rndGenerator(static_cast<unsigned int> (std::chrono::system_clock::now().time_since_epoch().count())); std::uniform_int_distribution<int> distribution(0, 25); auto bestScore = std::make_pair<int, std::string>(0, std::string("")); auto alpha = base_alphabet(); int iteration = 0; auto start_time = std::chrono::system_clock::now(); while (true) { auto crt_time = std::chrono::system_clock::now(); if (std::chrono::duration_cast<std::chrono::seconds>(crt_time - start_time) > std::chrono::seconds(timeout)) break; auto score = alphabet_score(words, alpha); if (score > bestScore.first) { bestScore.first = score; bestScore.second = alphabet_string(alpha); std::cout << score << " \t" << alphabet_string(alpha) << " iteration= " << iteration << std::endl; } alter_alphabet(alpha, rndGenerator, distribution); iteration++; if ((iteration % 1000) == 0) alter_alphabet(alpha, rndGenerator, distribution); if ((iteration % 5000) == 0) alter_alphabet(alpha, rndGenerator, distribution); if ((iteration % 50000) == 0) shuffle_alphabet(alpha); } return bestScore; }
// Create all threads and initialize shader push constants void prepareMultiThreadedRenderer() { // Since this demo updates the command buffers on each frame // we don't use the per-framebuffer command buffers from the // base class, and create a single primary command buffer instead VkCommandBufferAllocateInfo cmdBufAllocateInfo = vkTools::initializers::commandBufferAllocateInfo( cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &primaryCommandBuffer)); // Create a secondary command buffer for rendering the star sphere cmdBufAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &secondaryCommandBuffer)); threadData.resize(numThreads); float maxX = std::floor(std::sqrt(numThreads * numObjectsPerThread)); uint32_t posX = 0; uint32_t posZ = 0; std::mt19937 rndGenerator((unsigned)time(NULL)); std::uniform_real_distribution<float> uniformDist(0.0f, 1.0f); for (uint32_t i = 0; i < numThreads; i++) { ThreadData *thread = &threadData[i]; // Create one command pool for each thread VkCommandPoolCreateInfo cmdPoolInfo = vkTools::initializers::commandPoolCreateInfo(); cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex; cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VK_CHECK_RESULT(vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &thread->commandPool)); // One secondary command buffer per object that is updated by this thread thread->commandBuffer.resize(numObjectsPerThread); // Generate secondary command buffers for each thread VkCommandBufferAllocateInfo secondaryCmdBufAllocateInfo = vkTools::initializers::commandBufferAllocateInfo( thread->commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY, thread->commandBuffer.size()); VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &secondaryCmdBufAllocateInfo, thread->commandBuffer.data())); thread->pushConstBlock.resize(numObjectsPerThread); thread->objectData.resize(numObjectsPerThread); for (uint32_t j = 0; j < numObjectsPerThread; j++) { float theta = 2.0f * float(M_PI) * uniformDist(rndGenerator); float phi = acos(1.0f - 2.0f * uniformDist(rndGenerator)); thread->objectData[j].pos = glm::vec3(sin(phi) * cos(theta), 0.0f, cos(phi)) * 35.0f; thread->objectData[j].rotation = glm::vec3(0.0f, rnd(360.0f), 0.0f); thread->objectData[j].deltaT = rnd(1.0f); thread->objectData[j].rotationDir = (rnd(100.0f) < 50.0f) ? 1.0f : -1.0f; thread->objectData[j].rotationSpeed = (2.0f + rnd(4.0f)) * thread->objectData[j].rotationDir; thread->objectData[j].scale = 0.75f + rnd(0.5f); thread->pushConstBlock[j].color = glm::vec3(rnd(1.0f), rnd(1.0f), rnd(1.0f)); } } }