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]