打破循环循环

时间:2013-03-26 19:08:58

标签: c++ visual-c++ parallel-processing

#include<iostream>
#include<fstream>
#include<time.h>
#include<omp.h>

using namespace std;
static long num_steps = 100;
#define NUM 8
double step;

void main()
{
    clock_t time =clock();
    ofstream result;
    result.open ("Result.txt");
    int a[100];
    double pi, sum=0.0; 
    step = 1.0/(double) num_steps;

    #pragma omp parallel num_threads(NUM)
    {           
        int i, ID;    
        double x, psum= 0.0; 
        int nthreads = omp_get_num_threads();
        ID = omp_get_thread_num();   
        for (i=ID;i<= num_steps; i+=nthreads)
        {
            x = (i+0.5)*step;
            psum += 4.0/(1.0+x*x);
        }
        #pragma omp critical
        sum += psum;
    }

    pi = step * sum; 
    for (int j=0;j<100;j++)
    result<<a[j]<<endl;

    time = clock() - time;

    result << "Time Elapsed: " << (((double)time)/CLOCKS_PER_SEC) << endl;

    result <<"======================================================================================="<<endl;
    result.close();
}

问题是: for (i=ID;i<= num_steps; i+=nthreads) 以下for循环按以下顺序执行线程: 01234567 01234567 01234567等... 赋值是将for循环更改为,以便线程均匀分布并以圆形方式分配。首先是零,然后是两个......然后是七人组 我该怎么改变forloop?

1 个答案:

答案 0 :(得分:0)

你必须使用某种线程同步...
你标记Visual Studio所以我假设Windows平台......

最近这成了我的最爱:

// init
CRITICAL_SECTION hnd;
InitializeCriticalSectionAndSpinCount(&hnd,0x00000400);

// start lock
EnterCriticalSection(&hnd);
// stop lock
LeaveCriticalSection(&hnd);

// exit
DeleteCriticalSection(&hnd);

但还有很多其他方法。

  • 您也可以尝试制作自己的锁或无锁线程
  • 但请注意,在像Windows 7这样的新操作系统中,不同的过程是sheduler
  • 并且倾向于疯狂
  • 我的意思是在以前的操作系统上100%工作无锁代码现在不稳定或冻结
  • 所以我更喜欢使用操作系统锁。

如果您错误地使用锁定,则可能会失去多线程加速的任何好处。

如果您只是担心您的解决方案不能同时计算线程
你的情况不是平行但是连续的,而不是由此引起的:

  1. 处理时间粒度。

    • 任何受约束的任务都被划分为大块的时间。
    • 如果你的任务太短,那么它就会很快完成,然后其他任务就会开始执行。
    • 测试尝试更大的有效负载(计算时间>几秒)
    • 大大增加周期数
    • 添加睡眠(时间ms)以获得更长的计算时间
    • 如果输出会混合,那就是
    • 如果没有那么你仍处于粒度边界
    • 或您的多线程代码错误
  2. 错误的多线程代码

    • 你是否支持你的线程同时创建/运行?
    • 或者您是否同步错误? (比如直到上一个任务结束)
    • 还有一些编译器会做大量的volatile变量(为它添加锁定,有时会做很奇怪的事情......我多次难以接受,但主要是在MCU平台和Eclipse上)
  3. 单核

    • 在某些情况下,如果您只有1个CPU /核心/计算机进行处理
    • 或只是将关联掩码设置为单CPU
    • 在一些算法窗口上,sheduler不会均匀地计算CPU时间
    • 即使是进程/线程优先级/类
    • 也是如此
    • 在Windows 7上有时会出现类似的内容,即使有更多的CPU ......
    • 特别是代码与内核模式代码混合使用
  4. 要玩粒度,你可以使用他的:

    // obtain OS time capabilities
    TIMECAPS tim; 
    timeGetDevCaps(&tim,sizeof(tim));
    
    // set new granularity
    if (timeBeginPeriod(time ms)!=TIMERR_NOERROR) log("time granularity out of range");
    
    // return to previous hranularity
    timeEndPeriod(time ms ... must be the same as beginperiod);out of range");
    

    PS。非常好的关于此的事情就在这里:

    http://bitflipgames.com/2011/05/09/multithreaded-programming-part-1-the-critical-section-lock/ http://bitflipgames.com/2011/05/17/multithreaded-programming-part-2-multiple-readersingle-writer-lock/ http://bitflipgames.com/2011/05/20/multithreaded-programming-part-2-5-mrsw-lock-code/ http://bitflipgames.com/2011/05/25/multithreaded-programming-part-3-going-lockless/