爱刷题的有福了,邻居家的小孩都爱刷😋https://leetgpu.com
现在一般都cuda了,感兴趣的可以去看【【NVIDIA】CUDA官方入门课】 https://b23.tv/WX3pPM6前年的课,但是入门还是挺好的,ppt很简练
some qa
semaphore.h
sem_init初始化(线程/进程共享+初始值)
sem_wait(P抢资源)
sem_post(V放资源)
sem_destroy销毁,核心管线程同步互斥。
生产消费者_示例代码
#include <semaphore.h>
#include <stdio.h>
#include <pthread.h>
#define BUF_SIZE 3
int buf[BUF_SIZE], idx=0;
sem_t empty; // 空缓冲区数(初始3)
sem_t full; // 满缓冲区数(初始0)
sem_t mutex; // 互斥锁(保护缓冲区)
// 生产者
void* producer(void* arg) {
for (int i=1; i<=5; i++) {
sem_wait(&empty); // 申请空缓冲区
sem_wait(&mutex);
buf[idx++] = i;
printf("生产:%d\n", i);
sem_post(&mutex);
sem_post(&full); // 释放满缓冲区
}
return NULL;
}
// 消费者
void* consumer(void* arg) {
for (int i=1; i<=5; i++) {
sem_wait(&full); // 申请满缓冲区
sem_wait(&mutex);
int data = buf[--idx];
printf("消费:%d\n", data);
sem_post(&mutex);
sem_post(&empty); // 释放空缓冲区
}
return NULL;
}
int main() {
sem_init(&empty, 0, BUF_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
pthread_t p, c;
pthread_create(&p, NULL, producer, NULL);
pthread_create(&c, NULL, consumer, NULL);
pthread_join(p, NULL);
pthread_join(c, NULL);
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
比如某些dp,没有dp[i] 怎么算 dp[i+1]
(++同步+并发++)前序dp[i]算完发信号,唤醒线程算dp[i+1],衔接依赖
- CPU一般用 semaphore.h 靠信号量控线程同步
- GPU可以用CUDA流靠异步调度分阶段的并行
核心思想都是"++分任务+控顺序++"的来并发
em主要看dp有没有可并行的分支子问题,eg多维dp/分组dp..
信号量控依赖+多线程并行处理无依赖的子问题,只要并行处理的++任务计算量 > 切换开销(eg. dp子问题是复杂运算)++,整体效率还是比单线程高的(设计哲学: 寻找平衡点)
cpu vs gpu
CUDA处理大规模并行DP的常用工具(比如高维DP、批量子问题
++CPU处理中小规模并行DP(子问题复杂度高但数据量不大),而CUDA更适合超大规模DP(比如百万级子问题并行)++
两者是互补场景