我有4个线程,我想一次启动3个功能.每个函数都需要一个线程.
但是这段代码每次启动4次
#pragma omp parallel
{
Func1();
Func2();
Func3();
}
Run Code Online (Sandbox Code Playgroud)
我有这个结果:
Func*1*开始了
Func*1*开始了
Func*1*开始了
Func*1*开始了
Func*1*完成了
Func*1*完成了
Func*1*完成了
Func*1*完成了
Func*2*开始了
Func*2*开始了
Func*2*开始了
Func*2*开始了
Func*2*完成了
Func*2*完成了
Func*2*完成了
Func*2*完成了
...
我应该如何更改代码以显示如下:
Func*1*开始了
Func*2*开始了
Func*3*开始了
Func*2*完成了
Func*1*完成了
Func*3*完成了
我正在尝试编写一个OpenMp程序.我有一个for循环,迭代100次.我把它分成10个线程.每个线程运行10次迭代并根据某些条件生成一些计数.因此,根据这个逻辑,每个线程将生成自己的计数.
我想要的只是将此计数复制到一个变量,该变量将保存所有线程中所有计数的总和.如果我们让这个变量(共享)在循环中写入,我猜它会序列化线程.我只想将每个线程的最后一个计数复制到一个全局变量中.这样我将只序列化10个赋值语句.我尝试使用,lastprivate但我对如何使用它满足我的要求感到困惑.
这是我的代码
#pragma omp parallel for private(i) schedule(dynamic) shared(count)
for (i = 1; i <= 100 ; i++)
{
if(i%2==0)
count++;
}
printf("Total = %d \n", count);
Run Code Online (Sandbox Code Playgroud) 假设我有两个功能:
Fun1();
Fun2();
Run Code Online (Sandbox Code Playgroud)
这些函数是独立的,如果我可以并行运行它们(即,Fun1在一个线程和Fun2另一个线程上运行),任务将得到改进.我使用的是Visual Studio 2012 - 所以Open MP 2.0.
是否有一个直接的方式(没有任何并行区域的线程数测试或用于循环dodginess)来实现这一目标?OpenMP是否提供此类功能?
我试图寻找在parallel和task指令作为一个地方开始,但我发现,大部分的文献中有详尽的难以理解,但没有找到任何的例子...
这是我的代码的大纲:
#pragma omp parallel default(shared)
{
for(i; i<lim; i++)
do_work();
}
Run Code Online (Sandbox Code Playgroud)
过了一会儿:
do_work(){
foo();
bar();
}
foo(){
#pragma omp for //etc
for(i;i<l;i++) //your typical loop
}
bar(){ //here's the interesting part
int i;
int result;
#pragma omp for reduction(+:result) private(i)
for(i=0; i<lim; i++)
result++;
}
Run Code Online (Sandbox Code Playgroud)
编译时我收到以下错误:
减少变量'result'在外部上下文中是私有的
这不应该发生,因为根据IBM编译器文档的reduction条款
使用指定的运算符对列表中的所有标量变量执行减少.列表中的减少变量用逗号分隔.
为每个线程创建列表中每个变量的私有副本.在语句块的末尾,缩减变量的所有私有副本的最终值以适合于操作符的方式组合,并且结果被放回到共享缩减变量的原始值中.
减少条款中指定的变量:
- 必须是适合操作员的类型.
- 必须在封闭的上下文中共享.
- 不能是const限定的.
- 不能有指针类型.
强调补充说.由于外部并行区域应该处理所有变量shared,这意味着一旦发现它的减少就result应该转换为private.至少虽然它不应该private在外部范围内考虑,因为外部范围已明确告知每个变量shared.这是我困惑的根源.
当然我使用的是GCC而不是IBM编译器,但这种情况有区别吗?
所以我想我的问题是:为什么OpenMP会处理减少变量.作为私有变量,它之前被声明为在外部上下文中共享?
我只有减少这个问题,其他一切都按预期工作(特别是当有一个例子完全相同的事情).
我已经在这个网站上看到了几个关于这个问题的帖子.但是,我认为我的严格代码由于创建线程而产生的开销并且所有这些都不应该是一个大问题,现在开放的mp变得慢得多!我正在使用带有gfortran 4.6.3的四核机器作为我的编译器.以下是测试代码的示例.
Program test
use omp_lib
integer*8 i,j,k,l
!$omp parallel
!$omp do
do i = 1,20000
do j = 1, 1000
do k = 1, 1000
l = i
enddo
enddo
enddo
!$omp end do nowait
!$omp end parallel
End program test
Run Code Online (Sandbox Code Playgroud)
如果我在没有打开mp的情况下运行它,此代码大约需要80秒,但是,打开mp,大约需要150秒.我在其他严肃的代码中看到了同样的问题,在串行模式下运行时间约为5分钟左右.在这些代码中,我注意到从线程到线程没有依赖关系.那么为什么这些代码变慢而不是更快?
提前致谢.
我正在使用英特尔编译器OpenMP 4.0开发Intel E5(6核,12个线程)
为什么这段代码SIMD-ed比并行SIMD-ed更快?
for (int suppv = 0; suppv < sSize; suppv++) {
Value *gptr = &grid[gind];
const Value * cptr = &C[cind];
#pragma omp simd // vs. #pragma omp parallel for simd
for (int suppu = 0; suppu < sSize; suppu++)
gptr[suppu] += d * cptr[suppu];
gind += gSize;
cind += sSize;
}
Run Code Online (Sandbox Code Playgroud)
随着更多线程,它变得更慢.
编辑1:*grid是4096*4096矩阵,数据结构:vector<complex<double>>
*C是2112*129*129矩阵,数据结构:vector<complex<double>>
*gSize = 4096*sSize = 129.
我有一个用于多线程应用程序的简单代码,但是无论我传递它的线程数是多少,它都只能使用一个线程执行。最初,我认为这是计算机的问题,但是我尝试了另一台计算机,但是它也无法正常工作。我有什么事吗 如果有帮助,我正在使用Visual Studio 2015。
int th_id, nthreads;
#pragma omp parallel private(th_id) shared(nthreads) num_threads(3)
{
th_id = omp_get_thread_num();
#pragma omp critical
{
cout << "Hello World from thread " << th_id << '\n';
}
#pragma omp barrier
#pragma omp master
{
nthreads = omp_get_num_threads();
cout << "There are " << nthreads << " threads" << '\n';
}
}
Run Code Online (Sandbox Code Playgroud) #include "stdio.h"
#include "omp.h"
void main() {
omp_set_num_threads(4);
#pragma omp parallel
{
int numberOfThreads = omp_get_num_threads;
int ID = omp_get_thread_num;
printf("%d %d \n",ID,numberOfThreads);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的答案是:
4196016 4196064
4196016 4196064
4196016 4196064
4196016 4196064
Run Code Online (Sandbox Code Playgroud)
我用以下命令编译程序:
gcc -O3 -fopenmp -Wall test.c
Run Code Online (Sandbox Code Playgroud)
我只收到一些警告信息:
test.c: In function ‘main’:
test.c:8:24: warning: initialization makes integer from pointer
without a cast [enabled by default]
int numberOfThreads = omp_get_num_threads;
^
test.c:9:11: warning: initialization makes integer from pointer
without a cast [enabled by default]
int ID = omp_get_thread_num; …Run Code Online (Sandbox Code Playgroud) I am doing the Eratosthenes Sieve algo to find prime numbers before n. Idea is to mark off all the multiples of a prime. However, it did not achieve a performance increase as the number of threads scale up.
It cost 0.009 seconds using 100 threads and 0.006 seconds using 1 thread to find the prime numbers before 100000.
#pragma omp parallel num_threads(t)
{
#pragma omp for
for (int index = 2; index <= N; index++) {
list_of_nums[index - 2] …Run Code Online (Sandbox Code Playgroud) 每次我使用相同的参数执行cal()函数时,都会得到不同的输出。函数g()始终为相同的输入计算相同的结果。线程是否覆盖任何变量?
void cal(uint_fast64_t n) {
Bint num = N(n);
Bint total = 0, i, max_size(__UINT64_MAX__);
for(i = 1; i <= num; i+= max_size){
#pragma omp parallel shared(i,num,total)
{
int id = omp_get_thread_num();
int numthreads = omp_get_num_threads();
Bint sum(0), k;
for(uint64_t j = id; (j < __UINT64_MAX__); j+=numthreads){
k = i+j;
if(k > num){
i = k;
break;
}
sum = sum + g(k);
}
#pragma omp critical
total += sum;
}
}
std::cout << total << std::endl;
}
Run Code Online (Sandbox Code Playgroud) openmp ×10
c++ ×6
c ×4
concurrency ×1
fortran ×1
function ×1
gcc ×1
performance ×1
visual-c++ ×1