【问题标题】:C++ multithread algorithm creating several threads running on the same CPU threadC++ 多线程算法创建在同一个 CPU 线程上运行的多个线程
【发布时间】:2018-07-03 23:30:41
【问题描述】:

我是多线程的新手,我会尽量说清楚。我正在使用标准库 std::thread 在 C++ 中创建多线程算法。我的代码正在编译和运行,没有错误。我把两个线程的代码。正在创建两个线程,其 id 与主线程不同(我使用 getid() 和 Visual Studio 中的线程窗口进行了检查)。问题是我没有及时获得,而且我的 CPU 的百分比利用率是相同的,所以它们似乎运行在同一个 CPU 线程上。

这是否意味着线程不会自动意味着在不同的 CPU 内核和线程上运行以获得时间?

我是否需要添加指令或将此代码与多线程库结合使用?或者只是一个错误? 任何帮助将不胜感激,谢谢

double internalenergy=0;
unsigned int NUM_THREADS = std::thread::hardware_concurrency();
NUM_THREADS=2;
 vtkIdType num_cells = referencemesh_->GetNumberOfCells();
 int start_node[8];
 int end_node[8];
 int intervalle=num_cells/NUM_THREADS;
for( unsigned int i=0; i < NUM_THREADS; ++i )
{
    start_node[i] = (float)num_cells*i/NUM_THREADS;       
    end_node[i]   = (float)num_cells*(i+1)/NUM_THREADS;
}
const double* pointeurpara;
pointeurpara=&params(0);

double value1=0;
double* P_value1;
P_value1=&value1;

double value2=0;
double* P_value2;
P_value2=&value2;

std::thread first(threadinternalenergy,activemesh,referencemesh_,start_node[0],P_value1,pointeurpara);
std::thread second (threadinternalenergy,activemesh,referencemesh_,start_node[1],P_value2,pointeurpara);
first.join(); 
second.join();
double displacementneighpoint=*P_value1+*P_value2;

这里是threadinternalenergy的源码

void threadinternalenergy(vtkSmartPointer<vtkPolyData>, 
activemesh,vtkSmartPointer<vtkPolyData> referencemesh,int startcell,double* 
displacementneighpoint,const double* p) 
{
 unsigned long processnumber;
 processnumber=GetCurrentProcessorNumber();
 cout<<"process "<<processnumber<<endl;

unsigned int NUM_THREADS = std::thread::hardware_concurrency();
NUM_THREADS=2;
vtkIdType num_cells = referencemesh->GetNumberOfCells();
int intervalle=num_cells/NUM_THREADS;
int endcell=startcell+intervalle;
//cout<<"start cell "<<startcell<<endl;
//cout<<"end cell "<<endcell<<endl;
int numcell_th=startcell-endcell;

 vtkSmartPointer<vtkEdgeTable> vtk_edge_tableT = 
vtkSmartPointer<vtkEdgeTable>::New();
  vtk_edge_tableT->InitEdgeInsertion(numcell_th*3);

  // Initialize edge table
  vtkSmartPointer<vtkEdgeTable> vtk_edge_table = 
vtkSmartPointer<vtkEdgeTable>::New();
  vtk_edge_table->InitEdgeInsertion( numcell_th*3 );

  cout<<"start cell "<<startcell<<endl;

 for( vtkIdType i=startcell; i < endcell; ++i )
  {   
    vtkCell* cell = referencemesh->GetCell( i );
 // cout<<"cell"<<endl;
    // Traverse edges in cell -- assuming a linear cell (line, triangle; NOT 
  rectangle)
    for( vtkIdType j=0; j < cell->GetNumberOfEdges(); ++j )
    {
        // cout<<"edge"<<endl;
      vtkCell* edge = cell->GetEdge( j );

      vtkIdType pt0 = edge->GetPointId(0);
      vtkIdType pt1 = edge->GetPointId(1);


    //consider edge if a displacement has been point by at least one point
        //if(params(pt0)!=0 || params(pt1)!=0){


          if( vtk_edge_table->IsEdge( pt0, pt1 ) == -1 ){     // If this edge 
     is not in the edge table
                vtk_edge_table->InsertEdge( pt0, pt1 );
              //acess point coordinate
             // vtkPoints* listpoints=edge->GetPoints();
              double p0 [3];
              double p1 [3];
              referencemesh->GetPoint(pt0,p0);
              referencemesh->GetPoint(pt1,p1);


                //2e Mesh (Mesh transform)
                 double p0T [3];
              double p1T [3];
              activemesh->GetPoint(pt0,p0T);
              activemesh->GetPoint(pt1,p1T);


                    // If this edge is not in the edge table
                vtk_edge_tableT->InsertEdge( pt0, pt1 );


                //find displacement difference for 2 points sharing an edge
                double squaredDistancep0 = 
                vtkMath::Distance2BetweenPoints(p0, p0T);
                double distancep0 = sqrt(squaredDistancep0);
                double squaredDistancep1 = 
                vtkMath::Distance2BetweenPoints(p1, p1T);
                double distancep1 = sqrt(squaredDistancep1);
                double difference = abs(distancep0 - distancep1);
                difference=((difference+1)*(difference+1))-1;
                //if(difference>0.25){
                    //cout<<"grosse difference "<<difference<<endl;
                //}
                *displacementneighpoint+=difference;
                //displacementpointneigh.push_back(difference);



             }

        //}

    } 
  }
 cout<<"Fin du thread "<<endl;
 }

【问题讨论】:

标签: c++ multithreading stdthread


【解决方案1】:

线程可能在不同的内核上运行。这并不一定意味着程序会更快。它可能比使用一个线程运行得慢得多。线程必须同时做足够的工作来证明线程创建和同步的开销是合理的。有很多陷阱。一个可能的问题是线程过于频繁地共享(或“错误共享”)内存。

是的,线程背后的一个主要思想是“进行并发”。但这可以通过只有一个内核的 CPU 来完成!或者它可能无法很好地处理大量内核。

我编写了一个系统来控制处理计算机晶片的机器人。它运行在具有一个核心的 CPU 上,但它强烈依赖于并发性。并发是由于 CPU 以外的其他设备与其同时运行造成的,例如一个伺服放大器和一个网卡。一个高优先级线程专门处理通过网络管理伺服。其他线程利用空闲时间来规划轨迹,与主机通信等......当伺服控制线程因为网卡有伺服响应而唤醒时,它立即接管CPU并做它的东西。

今年在 cppCon 上有一个主题为“当一微秒是永恒”的演讲。这家伙编写了其中一个鬼鬼祟祟的股票交易系统。对他而言,重要的是他能以多快的速度处理将他与市场连接起来的网络。为了获得他需要的吞吐量,他使用了一台禁用了三个内核的 4 核机器。为什么?因为他找不到足够好的1核机。

我还写了一个类,它使用多线程在多核机器上进行一些计算。它惨败。有些任务不适合分而治之。

【讨论】:

  • 谢谢,关于内存共享,线程确实都使用相同的数据:activemesh,它会增加时间吗?我应该避免这种情况吗?目前,通常可能需要 1 到 2 秒(它用于进行数千次迭代的优化),1 秒是否太短而无法使用多线程进行优化?
  • 当两个线程访问同一个缓存行并且至少有一个线程写入时,硬件或操作系统必须争先恐后地让它们达成一致。进行简单的缓存访问可能需要 30 倍的时间。我不能在这里上课。找一本比我了解更多的人写的书。
  • 好吧,它只是读取共享数据,但也许它仍然做类似的事情......我会尝试找到更多信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多