【问题标题】:Difference in execution time in Windows shell and Git bash shell on windows 7Windows 7 上的 Windows shell 和 Git bash shell 的执行时间差异
【发布时间】:2020-07-05 22:13:03
【问题描述】:

我有一个示例代码要优化

#include <iostream>
#include <vector>
#include <memory>
#include <fstream>
#include <assert.h>
#include <pthread.h>
#include <unistd.h>

template<typename NumType=float>
void RenderSphereOnScreen(const NumType* const _coords)
{
   std::cout<<_coords[0]<<" "<<_coords[1]<<" "<<_coords[2]<<std::endl; //assume
}

template<typename NumType>
class SphereRenderTask
{
    NumType  _coords[3];
    public:
 SphereRenderTask(const NumType& x, const NumType& y, const NumType& z)
{
    if(std::is_same<NumType, int>::value || std::is_same<NumType, float>::value || std::is_same<NumType, double>::value)
    {
        _coords[0] = x;
        _coords[1] = y;
        _coords[2] = z;
    }
    else
    {
        std::cout << "Error.unknown class type!!\n";
        assert(0);
    }
}
 void operator()() const
 {
    RenderSphereOnScreen(_coords);
 }
};

std::vector<SphereRenderTask<double>*> taskList;
const int THREADS = 3;
void *renderThread(void *index)
{
    int tid = *((int *)index);
    int max = -1;
    int i = tid*(taskList.size()/THREADS);
    max = (tid+1)*(taskList.size()/THREADS);

    for( std::vector<SphereRenderTask<double>*>::iterator iter=taskList.begin() + i; i<max;)
    {
        (**iter)();
        i++;
        iter++;
    }

}

void StartRendering(const char* const inputFilePath)
{
    void sequential_render();
    void multithreaded_render();
   taskList.clear(); //init
   std::ifstream inputfile(inputFilePath);

   double x,y,z;

   while (inputfile >> x >> y>> z)
   {
     taskList.push_back(new SphereRenderTask<double>(x,y,z));
   }
    int y1 = taskList.size();
    inputfile.close();



    if(!THREADS)
        sequential_render();
    else
        multithreaded_render();
}

void sequential_render()
{
    for(std::vector<SphereRenderTask<double>*>::iterator iter=taskList.begin(); iter!=taskList.end(); ++iter)
    {
       (**iter)();
    }
}
void multithreaded_render()
{
    pthread_t tid[THREADS];
    for(int i=0;i<THREADS;i++)
    {
       int tmp = i;
       pthread_create(&tid[i], NULL, renderThread, &tmp);
       pthread_join(tid[i], NULL);
    }
}

int main(int argc, const char* argv[])
{
    StartRendering("sphere.txt");
    return 0;
}

这是做什么的:

  1. 读取包含 100k 行 (x,y,z) 的文件名“sphere.txt”,可以是浮点数

    例子:

     136 562 293
     629 399 497
     682 642 995
     739 351 869
     607 968 7
     262 788 863
    .... 
    

    最多 100k 行

  2. 保存在数据结构中,taskList指针向量

  3. 然后使用sequential_render 或multithreaded_render 在屏幕上显示

对此我有两个问题:

  1. 运行它会在 windows shell 和 git bash shell 上提供差异运行时间,两者都在 windows 上。(编译器 mingw g++ 5.1.0)

    Windows 外壳:

    git bash 外壳

  2. 为什么使用多线程并不能提高运行时间?我在 Windows 和 Linux 上都试过了。

【问题讨论】:

  • 你的“多线程”版本启动一个线程并等待它完成,然后它启动下一个线程并等待它完成,然后它启动下一个线程...
  • 您主要测量在控制台中打印内容所需的时间,而 Windows 的 cmd 速度非常慢。
  • 我怀疑从多线程打印到std::cout 会有用。不同线程的输出很可能会混淆。除非你同步它们,否则任何时候只有一个线程可以工作,所以你实际上回到了单个线程。
  • 当您实际同时运行多个线程时会遇到的一个问题是您将&amp;tmp 传递给线程,而tmp 的生命周期可能在线程启动时已经结束。
  • 在 Windows 中,一些终端进程非常慢。我记得一个 Meteor 项目。在 Virtual Box 中启动 Linux 并在 Virtual Box 中构建比在 Windows 中构建而不在后台运行 Virtual Box 更快。现在我了解到我可能也可以使用 Git Bash Shell 而不是 PowerShell 或 Windows Cmd

标签: c++ c multithreading algorithm operating-system


【解决方案1】:

这里有个小结论:

  1. 就是这样。 CMD 非常慢。 This question 稍微解释了一下,并提供了一些可能很有趣的链接。

  2. 你实际上并没有多线程:

    pthread_t tid[THREADS]; // Array of threads
    
    for(int i=0;i<THREADS;i++)
    {
        int tmp = i;
        pthread_create(&tid[i], NULL, renderThread, &tmp); // Create one thread
        pthread_join(tid[i], NULL); // wait for it to complete
    }
    

    那么在任何给定时间有多少线程在工作?没错,只有一个。所以打印元素的基本时间与单线程版本相同,但创建和加入线程需要时间,而单线程版本不需要。正确使用多线程应该是:

    pthread_t tid[THREADS]; // Array of threads
    int tmps[THREADS]; // each thread wants it's own tmp
    
    //start all the threads
    for(int i = 0; i < THREADS; i++)
    {
        tmps[i] = i;
        pthread_create(&tid[i], NULL, renderThread, &tmps[i]);
    }
    
    // join them all
    for(int i = 0; i < THREADS; i++)
    {
        pthread_join(tid[i], NULL); // wait for it to complete
    }
    

但正如我在评论中已经提到的,从多个线程写信给std::cout 只会混淆线路。写入任何东西通常都需要一些同步,所以大多数时候你的线程只会等待。在这里使用线程似乎没有用。

【讨论】:

    猜你喜欢
    • 2014-10-30
    • 2013-05-16
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2016-09-05
    • 2017-06-14
    相关资源
    最近更新 更多