【问题标题】:Intel TBB, parallel_pipeline, error when I pass const char* between stages英特尔 TBB,parallel_pipeline,当我在阶段之间传递 const char* 时出错
【发布时间】:2018-01-26 00:30:04
【问题描述】:

我有以下管道:

parallel_pipeline(20,
       make_filter<void,const char*>(
          filter::serial,
          [&](flow_control& fc)->const char*
          {
            getline(fe,orden_fichero);
            if(fe.eof())
            {
              fc.stop(); // stop processing
              return nullptr;
            }
            else
            {
              return orden_fichero.c_str();
            }
          }
        ) &
      make_filter<const char*,void>(
          filter::parallel,
          [&](const char* p){

              string orden(p);
          }
        )
      );

之前,当我使用字符串而不是const char*,并且第一个返回是orden_fichero 而不转换为const char* 时,程序运行良好,但速度很慢。我已经看到使用const char* 可以提高程序的性能,但是这样在管道的第二阶段没有正确接收到某些行(某些行缺少字符)例如在10M lines 文件,26 行对应 orden 字符串,大小为 0,9 的大小在 2 到 35 之间,其余的都正确接收(order 变量有 36 个字符或更多)

  • 如何从第一个管道中正确接收一个 const char* 来介绍第二个管道?

  • 有一些方法可以读取英特尔 TBB 中的文件,以便在每一行上并行执行操作,并将结果以一种更好的方式保存在一个向量中,而不是我正在尝试的方式?

【问题讨论】:

    标签: c++ string char ifstream tbb


    【解决方案1】:

    问题是您首先返回了orden_fichero 的副本(我猜是std::string)。使用您当前的代码,您将返回一个指向 orden_fichero 内部数据的指针,因此当线程 1(第一个管道阶段)从文件中读取一行并将其存储在 orden_fichero 中时,数据已损坏,从线程 2(第二个管道阶段)。

    here 显示了一些如何正确返回 c 字符串的方法(特别是我会推荐版本 2)。但这又会分配大量内存,并且很可能几乎与返回 std::string 一样低效。

    您可以尝试在parallel_pipeline 之外创建一个新字符串,将 orden_fichero 的c_str 复制到该字符串中,然后返回指向该字符串的指针。但我不确定这是否能正常工作......

    std::string another_string;
    parallel_pipeline(20,
           make_filter<void,const char*>(
              filter::serial,
              [&](flow_control& fc)->const char*
              {
                getline(fe,orden_fichero);
                if(fe.eof())
                {
                  fc.stop(); // stop processing
                  return nullptr;
                }
                else
                {
                  another_string = orden_fichero;
                  return another_string.c_str();
                }
              }
            ) &
          make_filter<const char*,void>(
              filter::parallel,
              [&](const char* p){
    
                  string orden(p);
              }
            )
          );
    

    因此,在将数据读入orden_ficherogetline 时,可以安全地使用another_string。但正如我所说,我不确定这是否会正常工作,因为第二个管道阶段的线程可能会在 const char* p 复制到 orden 之前被抢占,然后第一阶段的线程可能会覆盖 @987654333 @ 并使 p 无效。您可以尝试使用互斥锁保护another_string,但我想这会再次减慢速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 2023-03-25
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多