如何用OpenMP对比串行与并行代码时间并计算加速比?
问题分析与解决方案
为什么clock()测量的"串行时间"会随线程数增长?
clock()函数统计的是进程所有线程的CPU时间总和,不是真实的墙上时间(从任务开始到结束的实际流逝时间)。当你启用多线程时,多个线程的CPU执行时间会被累加,所以得到的数值会比单线程时更大——这根本不是串行时间,而是多线程的总CPU耗时,完全不能作为加速比的计算基准。
正确的加速比计算方式
加速比的定义是单线程执行任务的墙上时间除以多线程执行同一任务的墙上时间,这里必须统一用墙上时间(即omp_get_wtime()测量的时间):
- 单独运行一次单线程版本,用
omp_get_wtime()记录基准时间T_serial(比如你示例里的0.0231161s)。 - 运行N线程版本时,用
omp_get_wtime()记录并行时间T_parallel。 - 加速比计算公式:
加速比 = T_serial / T_parallel。
比如你示例中2线程的并行时间是0.0132717s,实际加速比就是0.0231161 / 0.0132717 ≈ 1.74,这个结果符合实际情况——因为线程调度、数据同步等额外开销,实际加速比永远达不到理论值。
代码修正建议
- 全程使用
omp_get_wtime()测量时间,彻底弃用clock()来计算加速比基准。 - 为了减少误差,建议多次运行取平均值,并且把FFTW的计划(
fftw_plan)创建放在计时范围之外——计划阶段的开销和线程数无关,我们要测量的是实际计算(fftw_execute)的加速比:
// 先单独创建FFTW计划(仅执行一次) fftw_init_threads(); fftw_plan_with_nthreads(nThreads); fftw_plan forward = fftw_plan_dft_3d(nx, ny, nz, input_array, output_array, FFTW_FORWARD, FFTW_ESTIMATE); // 计时仅包含核心计算部分 start_time = omp_get_wtime(); fftw_execute(forward); run_time = omp_get_wtime() - start_time; // 后续资源清理 fftw_destroy_plan(forward); fftw_cleanup();
- 固定单线程的基准时间,不要每次多线程测试都重新计算基准,确保加速比的对比基准统一。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

