C++ 在C+中用两种方法计算pi+;OpenMP

C++ 在C+中用两种方法计算pi+;OpenMP,c++,algorithm,openmp,montecarlo,C++,Algorithm,Openmp,Montecarlo,什么方法应该更快? 第一种方法是增加一个变量用于减少: #pragma omp parallel private(seed, x, y, i) reduction (+:counter) { seed = 25234 + 17 * omp_get_thread_num(); nproc = omp_get_thread_num(); #pragma omp parallel for for(i=0; i<prec/8; i++){ x = (

什么方法应该更快? 第一种方法是增加一个变量用于减少:

#pragma omp parallel private(seed, x, y, i) reduction (+:counter)
{
    seed = 25234 + 17 * omp_get_thread_num();
    nproc = omp_get_thread_num();
    #pragma omp parallel for
    for(i=0; i<prec/8; i++){
        x = (double)rand_r(&seed) / RAND_MAX;
                y = (double)rand_r(&seed) / RAND_MAX;
        if(x*x+y*y<1){
            counter++;
        } 

}
我认为我的代码错了还是我做了什么错事?

第二种方法中,您是受害者。这里有一个有趣的例子

当不同处理器上的线程修改 位于同一缓存线上的变量。这将使合同无效 缓存线并强制内存更新以保持缓存一致性

如果两个处理器对同一内存中的独立数据进行操作 地址区域可存储在一行中,缓存一致性好 系统中的机制可能会迫使整条线路穿过总线或 每次数据写入时都进行互连,从而强制内存暂停 浪费系统带宽

直觉上,我不认为第一种方法应该更慢。

实际上,您在每个线程上创建了一个私有副本,然后将最终结果应用到一个全局变量中。这种行为在某种程度上与共享数组相同,但这里的问题是,即使您的访问是独立的,也会得到错误的共享

reduce
变量是私有的,这使你的论点无效。我认为这不应该是重复的问题,即使答案有相同的结论,问题也不一样。(肯定不是最好的)@coincoin,虽然不是逐字逐句地问同一个问题,但核心前提是相同的。当然,SO上的任何人都可以自由地提出异议,并投票赞成重新讨论这个问题。@HristoIliev我个人并不介意,这很好!出于好奇,我们怎么能投票赞成重新讨论这个问题呢?我看不出我想我有最低限度的分数,对吗?@coincoin,我真的是指几乎所有人。您需要3000点才能访问关闭/重新打开投票-请参阅。
#pragma omp parallel private(seed, x, y, i , nproc)
{
    seed = 25234 + 17 * omp_get_thread_num();
    nproc = omp_get_thread_num();
    #pragma omp parallel for
    for(i=0; i<prec/8; i++){
        x = (double)rand_r(&seed) / RAND_MAX;
        y = (double)rand_r(&seed) / RAND_MAX;
        if(x*x+y*y<1){
            counter[nproc]++;
        } 

    }
}

double time = omp_get_wtime() - start_time;
int sum=0;
for(int i=0; i<8; i++){
    sum+=counter[i];

} 
first approach: 3.72423 [s]

second approach: 8.94479[s]