为何多线程FFTW性能不及单线程?附代码求问题排查
FFTW多线程性能低于单线程问题排查与疑问解答
代码中的关键问题分析
- 线程数设置无效:你当前代码中
fftw_plan_with_nthreads(1)明确指定用1线程,相当于单线程运行,自然看不到多线程性能提升。要测试多线程,需将这里改为大于1的数值(比如omp_get_num_procs()获取系统核心数,或手动设为2/4等),且必须在创建计划之前设置。 - 计划优化级别不足:使用
FFTW_ESTIMATE生成计划时,FFTW仅快速生成简单方案,不会针对多线程做性能调优。多线程场景建议改用FFTW_MEASURE(运行测试寻找较优方案)或FFTW_PATIENT(耗时更长但优化更充分),能显著提升多线程执行效率。 - 计时方式错误:
clock()统计的是总CPU时间(所有线程的CPU时间之和),多线程下该数值会比单线程高,但实际程序的墙钟运行时间(真实耗时)是减少的。应改用墙钟时间计时,比如clock_gettime(CLOCK_MONOTONIC)或gettimeofday(),才能正确反映多线程的速度提升。 - 输出语句错误:
printf(cpu_time_used);格式错误,正确写法应为printf("Time used: %f seconds\n", cpu_time_used);,否则会导致未定义行为。 - 冗余的OpenMP代码:注释的OpenMP并行循环(
#pragma omp parallel for)没必要——FFTW内部已处理单计划的多线程并行,外部再加OpenMP并行会导致线程嵌套,增加调度开销。
修改线程数后的性能预期
修改fftw_plan_with_nthreads的线程数,在合理范围内(不超过CPU物理核心数),通常能获得性能提升、加快运行速度,但需满足几个前提:
- 计划创建时机正确:必须在调用
fftw_plan_dft_r2c_2d/fftw_plan_dft_c2r_2d之前设置线程数,FFTW的计划会绑定创建时指定的线程配置,后续修改线程数不会生效。 - 数据规模足够:如果处理的数据量太小,线程调度、同步的开销会超过并行计算的收益,此时多线程可能比单线程更慢。你当前的1024x1024规模已足够发挥多线程优势。
- 使用合适的计划标志:如前文所说,
FFTW_MEASURE或FFTW_PATIENT能让FFTW针对多线程场景优化执行策略,效果远好于FFTW_ESTIMATE。 - 正确计时:用墙钟时间评估性能,避免被总CPU时间误导。
修正后的核心代码片段
// 启用多线程并设置线程数 fftw_init_threads(); int nthreads = omp_get_num_procs(); // 获取系统核心数 fftw_plan_with_nthreads(nthreads); // 使用FFTW_MEASURE生成优化计划 r2c_plan = fftw_plan_dft_r2c_2d(n1, n2, x, y, FFTW_MEASURE); c2r_plan = fftw_plan_dft_c2r_2d(n1, n2, y, z, FFTW_MEASURE); // 改用墙钟时间计时 struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); for(i = 0; i < 1000; i++){ fftw_execute(r2c_plan); fftw_execute(c2r_plan); } clock_gettime(CLOCK_MONOTONIC, &end); double cpu_time_used = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; printf("Wall time used: %f seconds\n", cpu_time_used);
内容的提问来源于stack exchange,提问作者lwt
相关产品推荐
相关产品推荐

