2012-06-12 28 views
0

我有OpenMP的使用如何组织正确的并行程序输出?

#pragma omp parallel for private(i) 
for (j=0;j<NUM_STEPS_J) { 

    for (i=0;i<NUM_STEPS_I;i++) { 

     std::cout << "Print some information about step i" << std::endl; 


    } 

    std::cout << "Check of item " << j << " finished" << std::endl; 
} 

什么是提供在我的情况下,正确的输出的最佳方式一样的C++程序?

我知道,用“printf”代替“cout”解决了这个问题。

但是,当我将“cout”更改为“printf”时,我的程序执行时间从约80秒增加到约120秒。 我认为,这对程序的生产力有着足够的影响。

解决这个问题没有“printf”的最好方法是什么?

是否可以在输出过程中以某种方式锁定“cout”功能?

+0

您可以考虑在运行时收集一些信息并以某种形式的数据结构存储它。然后在运行后打印报告。这样你就不会将你的计算和printint输出混合在一起。当然,你不会更新“现场”。 – Matthias

+0

是的,当然这是最有效的方法。但主要想法是在运行时打印这些信息。在其他情况下,信息“std :: cout <<”检查项目“<< j <<”已完成“<< std :: endl;”是无意义的,我可以删除它,并使用“#pragma omp critical”作为“std :: cout <<”打印有关step i“std :: endl;”的一些信息 –

回答

2

我会很惊讶地看到printf比输入输出流慢...(更多这样考虑您正在使用std::endl迫使缓冲的冲洗),但无论如何,你可以使用一个stringstream构造输出在一次,然后用已建好的线路调用printfstd::cout <<一次。

+0

我也很惊讶:) –

+0

如果我理解正确,以这种方式使用std :: cout“std :: cout << String << std :: endl”将永远不会在并行输出期间导致错误的输出? –

+0

@LuckyMan:是的,但是我会把'\ n''附加到'String',并将'std :: endl'改成'std :: flush'(如果你真的需要刷新)。这样,连续调用两个'operator <<'的竞争条件不会影响输出。通过使用'std :: endl;'你将新行绑定到第二个调用,另一个写在中间的线程将写入同一行(后面跟着两个换行符),你可能想避免这一行。 –