class MultithreadedApplication {
private:
// 线程相关成员
uint32_t threadCount;
std::vector<std::thread> workerThreads;
std::atomic<bool> shouldExit{false};
std::vector<std::atomic<bool>> threadWorkReady;
std::vector<std::atomic<bool>> threadWorkDone;
// 同步原语
std::mutex queueSubmitMutex;
std::condition_variable workCompleteCv;
// 资源管理器
ThreadSafeResourceManager resourceManager;
// 粒子系统数据
struct ParticleGroup {
uint32_t startIndex;
uint32_t count;
};
std::vector<ParticleGroup> particleGroups;
// ... 其他 Vulkan 资源 ...
public:
void initThreads() {
// 确定要使用的线程数(为主线程保留一个核心)
threadCount = std::max(1u, std::thread::hardware_concurrency() - 1);
// 初始化同步原语
threadWorkReady.resize(threadCount);
threadWorkDone.resize(threadCount);
for (uint32_t i = 0; i < threadCount; i++) {
threadWorkReady[i] = false;
threadWorkDone[i] = true;
}
// 为每个线程创建命令池
resourceManager.createThreadCommandPools(device, graphicsQueueFamilyIndex, threadCount);
// 将粒子划分为组,每组对应一个线程
const uint32_t particlesPerThread = PARTICLE_COUNT / threadCount;
particleGroups.resize(threadCount);
for (uint32_t i = 0; i < threadCount; i++) {
particleGroups[i].startIndex = i * particlesPerThread;
particleGroups[i].count = (i == threadCount - 1) ?
(PARTICLE_COUNT - i * particlesPerThread) : particlesPerThread;
}
// 启动工作线程
for (uint32_t i = 0; i < threadCount; i++) {
workerThreads.emplace_back(&MultithreadedApplication::workerThreadFunc, this, i);
}
}
void workerThreadFunc(uint32_t threadIndex) {
while (!shouldExit) {
// 等待工作准备就绪
if (!threadWorkReady[threadIndex]) {
std::this_thread::yield();
continue;
}
// 获取此线程的粒子组
const ParticleGroup& group = particleGroups[threadIndex];
// 获取此线程的命令缓冲
vk::raii::CommandBuffer& cmdBuffer = resourceManager.getCommandBuffer(threadIndex);
// 为此粒子组记录命令
recordComputeCommandBuffer(cmdBuffer, group.startIndex, group.count);
// 标记工作完成
threadWorkDone[threadIndex] = true;
threadWorkReady[threadIndex] = false;
// 通知主线程
workCompleteCv.notify_one();
}
}
void recordComputeCommandBuffer(vk::raii::CommandBuffer& cmdBuffer, uint32_t startIndex, uint32_t count) {
cmdBuffer.reset();
cmdBuffer.begin({});
// 绑定计算管线和描述符集
cmdBuffer.bindPipeline(vk::PipelineBindPoint::eCompute, *computePipeline);
cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute, *computePipelineLayout, 0, {*computeDescriptorSets[frameIndex]}, {});
// 添加推送常量以指定此线程的粒子范围
struct PushConstants {
uint32_t startIndex;
uint32_t count;
} pushConstants{startIndex, count};
cmdBuffer.pushConstants<PushConstants>(*computePipelineLayout, vk::ShaderStageFlagBits::eCompute, 0, pushConstants);
// 调度计算工作
uint32_t groupCount = (count + 255) / 256;
cmdBuffer.dispatch(groupCount, 1, 1);
cmdBuffer.end();
}
void signalThreadsToWork() {
// 通知所有线程开始工作
for (uint32_t i = 0; i < threadCount; i++) {
threadWorkDone[i] = false;
threadWorkReady[i] = true;
}
}
void waitForThreadsToComplete() {
// 等待所有线程完成工作
std::unique_lock<std::mutex> lock(queueSubmitMutex);
workCompleteCv.wait(lock, [this]() {
for (uint32_t i = 0; i < threadCount; i++) {
if (!threadWorkDone[i]) {
return false;
}
}
return true;
});
}
void cleanup() {
// 通知线程退出并等待
shouldExit = true;
for (auto& thread : workerThreads) {
if (thread.joinable()) {
thread.join();
}
}
// ... 清理其他资源 ...
}
};