并行计算-多媒体课件-并行程序设计-ch07OpenMP编程指南.ppt

上传人:qwe****56 文档编号:70014788 上传时间:2023-01-14 格式:PPT 页数:59 大小:393KB
返回 下载 相关 举报
并行计算-多媒体课件-并行程序设计-ch07OpenMP编程指南.ppt_第1页
第1页 / 共59页
并行计算-多媒体课件-并行程序设计-ch07OpenMP编程指南.ppt_第2页
第2页 / 共59页
点击查看更多>>
资源描述

《并行计算-多媒体课件-并行程序设计-ch07OpenMP编程指南.ppt》由会员分享,可在线阅读,更多相关《并行计算-多媒体课件-并行程序设计-ch07OpenMP编程指南.ppt(59页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、并行算法实践上篇 并行程序设计导论并行算法实践上篇 并行程序设计导论 单元单元单元单元I I 并行程序设计基础并行程序设计基础并行程序设计基础并行程序设计基础 单元单元单元单元II II 并行程序编程指南并行程序编程指南并行程序编程指南并行程序编程指南 单元单元单元单元III III 并行程序开发方法并行程序开发方法并行程序开发方法并行程序开发方法2023/1/142国家高性能计算中心(合肥)单元II 并行程序编程指南 第四章第四章第四章第四章 MPIMPI编程指南编程指南编程指南编程指南 第五章第五章第五章第五章 PVMPVM编程指南编程指南编程指南编程指南 第六章第六章第六章第六章 HPF

2、HPF编程指南编程指南编程指南编程指南 第七章第七章第七章第七章 OpenMPOpenMP编程指南编程指南编程指南编程指南2023/1/143国家高性能计算中心(合肥)第七章第七章 OpenMP编程指南编程指南 7.1 7.1 OpenMPOpenMP概述概述 7.2 7.2 OpenMPOpenMP编程风络编程风络 7.3 7.3 OpenMPOpenMP编程简介编程简介 7.4 7.4 运行库例程与环境变量运行库例程与环境变量 7.5 7.5 OpenMPOpenMP计算实例计算实例2023/1/144国家高性能计算中心(合肥)OpenMP概述 OpenMPOpenMP应用编程接口应用编程

3、接口APIAPI是在共享存储体系结构上的是在共享存储体系结构上的一个编程模型一个编程模型 包含编译制导包含编译制导(Compiler Directive)(Compiler Directive)、运行库例程、运行库例程(Runtime Library)(Runtime Library)和环境变量和环境变量(Environment(Environment Variables)Variables)支持增量并行化支持增量并行化(Incremental Parallelization)(Incremental Parallelization)2023/1/145国家高性能计算中心(合肥)OpenMP体

4、系结构2023/1/146国家高性能计算中心(合肥)什么是OpenMP 什么是什么是OpenMPOpenMP 应用编程接口应用编程接口APIAPI(Application Programming Interface Application Programming Interface)由三个基本由三个基本APIAPI部分(编译指令、运行部分和环境变量)构成部分(编译指令、运行部分和环境变量)构成 是是C/C+C/C+和和FortanFortan等的应用编程接口等的应用编程接口 已经被大多数计算机硬件和软件厂家所标准化已经被大多数计算机硬件和软件厂家所标准化 OpenMPOpenMP不包含的性质不

5、包含的性质 不是建立在分布式存储系统上的不是建立在分布式存储系统上的 不是在所有的环境下都是一样的不是在所有的环境下都是一样的 不是能保证让多数共享存储器均能有效的利用不是能保证让多数共享存储器均能有效的利用 2023/1/147国家高性能计算中心(合肥)OpenMP的历史 19941994年,第一个年,第一个ANSI X3H5ANSI X3H5草案提出,被否决草案提出,被否决 19971997年,年,OpenMPOpenMP标准规范代替原先被否决的标准规范代替原先被否决的ANSI ANSI X3H5X3H5,被人们认可,被人们认可 19971997年年1010月公布了与月公布了与Fortra

6、nFortran语言捆绑的第一个标准规语言捆绑的第一个标准规范范 19981998年年1111月月9 9日公布了支持日公布了支持C C和和C+C+的标准规范的标准规范 目前目前Fortran77Fortran77、Fortran90Fortran90、C C、C+C+语言的实现规范语言的实现规范已经完成已经完成 2023/1/148国家高性能计算中心(合肥)OpenMP的目标 标准性标准性 简洁实用简洁实用 使用方便使用方便 可移植性可移植性 2023/1/149国家高性能计算中心(合肥)OpenMP并行编程模型 基于线程的并行编程模型基于线程的并行编程模型(Programming Model

7、)(Programming Model)OpenMPOpenMP使用使用Fork-JoinFork-Join并行执行模型并行执行模型 2023/1/1410国家高性能计算中心(合肥)OpenMP程序结构 基于基于基于基于FortranFortran语言的语言的语言的语言的OpenMPOpenMP程序的结构程序的结构程序的结构程序的结构PROGRAM HELLOPROGRAM HELLOINTEGER VAR1,VAR2,VAR3INTEGER VAR1,VAR2,VAR3 !Serial code !Serial code !Beginning of parallel section.Fork

8、 a team of threads.Beginning of parallel section.Fork a team of threads.!Specify variable scoping !Specify variable scoping!$OMP PARALLEL PRIVATE(VAR1,VAR2)SHARED(VAR3)!$OMP PARALLEL PRIVATE(VAR1,VAR2)SHARED(VAR3)!Parallel section executed by all threads !Parallel section executed by all threads !Al

9、l threads join master thread and disband !All threads join master thread and disband!$OMP END PARALLEL!$OMP END PARALLEL !Resume serial code !Resume serial codeENDEND 2023/1/1411国家高性能计算中心(合肥)OpenMP程序结构 基于基于基于基于c/cc/c+语言的语言的语言的语言的OpenMPOpenMP程序的结构程序的结构程序的结构程序的结构#include#include main()main()int var1,v

10、ar2,var3;int var1,var2,var3;/*Serial code*/*Serial code*/*Beginning of parallel section.Fork a team/*Beginning of parallel section.Fork a team ofthreadsofthreads*/*/*Specify variable scoping*/*Specify variable scoping*/#pragmapragma ompomp parallel private(var1,var2)shared(var3)parallel private(var1

11、,var2)shared(var3)/*Parallel section executed by all threads*/*Parallel section executed by all threads*/*All threads join master thread and disband*/*All threads join master thread and disband*/*Resume serial code*/*Resume serial code*/2023/1/1412国家高性能计算中心(合肥)一个简单的OpenMP程序实例 基于基于基于基于C/C+C/C+语言的语言的语

12、言的语言的OpenMPOpenMP程序结构的一个具体实现程序结构的一个具体实现程序结构的一个具体实现程序结构的一个具体实现#include#include omp.homp.h intint main(intmain(int argcargc,char*,char*argvargv)intint nthreadsnthreads,tidtid;intint nprocsnprocs;char buf32;char buf32;/*Fork a team of threads */*Fork a team of threads */#pragmapragma ompomp parallel pa

13、rallel private(nthreadsprivate(nthreads,tidtid)/*Obtain and print thread id */*Obtain and print thread id */tidtid=omp_get_thread_numomp_get_thread_num();();printf(Helloprintf(Hello World from OMP thread%World from OMP thread%dndn,tidtid););/*Only master thread does this */*Only master thread does t

14、his */if(if(tidtid=0)=0)nthreadsnthreads=omp_get_num_threadsomp_get_num_threads();();printf(Numberprintf(Number of threads%of threads%dndn,nthreadsnthreads););return 0;return 0;2023/1/1413国家高性能计算中心(合肥)一个简单的OpenMP程序实例 运行结果运行结果 (setenvsetenv OMP_NUM_THREADS 8)OMP_NUM_THREADS 8)Hello World from OMP thr

15、ead 0Hello World from OMP thread 0Number of threads 8Number of threads 8Hello World from OMP thread 4Hello World from OMP thread 4Hello World from OMP thread 5Hello World from OMP thread 5Hello World from OMP thread 6Hello World from OMP thread 6Hello World from OMP thread 7Hello World from OMP thre

16、ad 7Hello World from OMP thread 2Hello World from OMP thread 2Hello World from OMP thread 1Hello World from OMP thread 1Hello World from OMP thread 3Hello World from OMP thread 32023/1/1414国家高性能计算中心(合肥)编译制导 语句格式语句格式#pragma ompdirective-nameclause,.newline制导指令前缀。对所有的OpenMP语句都需要这样的前缀。OpenMP制导指令。在制导指令前

17、缀和子句之间必须有一个正确的OpenMP制导指令。子句。在没有其它约束条件下,子句可以无序,也可以任意的选择。这一部分也可以没有。换行符。表明这条制导语句的终止。2023/1/1415国家高性能计算中心(合肥)编译制导 作用域作用域 静态扩展静态扩展 文本代码在一个编译制导语句之后,被封装到一个结构块中文本代码在一个编译制导语句之后,被封装到一个结构块中 孤立语句孤立语句 一个一个OpenMPOpenMP的编译制导语句不依赖于其它的语句的编译制导语句不依赖于其它的语句 动态扩展动态扩展 包括静态范围和孤立语句包括静态范围和孤立语句2023/1/1416国家高性能计算中心(合肥)作用域作用域动态

18、范围动态范围静态范围静态范围forfor语句出现在一个封闭的并行域中语句出现在一个封闭的并行域中 孤立语句孤立语句criticalcritical和和sectionssections语句出现在封闭的并行域之外语句出现在封闭的并行域之外#pragmapragma ompomp parallel parallel#pragmapragma ompomp for for for()for()sub1();sub1();sub2();sub2();void sub1()void sub1()#pragmapragma ompomp critical critical void sub2()void s

19、ub2()#pragmapragma ompomp sections sections 2023/1/1417国家高性能计算中心(合肥)并行域结构 并行域中的代码被所有的线程执行并行域中的代码被所有的线程执行 具体格式具体格式#pragmapragma ompomp parallel parallel clause,clauseclause,clausenewlinenewline clause=clause=if(if(scalar_expressionscalar_expression)private(list)private(list)shared(list)shared(list)de

20、fault(shared|none)default(shared|none)firstprivatefirstprivate(list)(list)reduction(operator:list)reduction(operator:list)copyincopyin(list)(list)2023/1/1418国家高性能计算中心(合肥)共享任务结构 共享任务结构将它所包含的代码划分给线程组的各成员共享任务结构将它所包含的代码划分给线程组的各成员来执行来执行 并行并行forfor循环循环 并行并行sectionssections 串行执行串行执行2023/1/1419国家高性能计算中心(合肥)

21、for编译制导语句 forfor语句指定紧随它的循环语句必须由线程组并行执行;语句指定紧随它的循环语句必须由线程组并行执行;语句格式语句格式#pragmapragma ompomp for for clause,clauseclause,clause newlinenewline clause=clause=Schedule(typeSchedule(type,chunk),chunk)orderedordered private(list)private(list)firstprivatefirstprivate(list)(list)lastprivatelastprivate(list)

22、(list)shared(list)shared(list)reduction(operator:list)reduction(operator:list)nowaitnowait 2023/1/1420国家高性能计算中心(合肥)for编译制导语句 scheduleschedule子句描述如何将循环的迭代划分给线程组中子句描述如何将循环的迭代划分给线程组中的线程的线程 如果没有指定如果没有指定chunkchunk大小,迭代会尽可能的平均分配给大小,迭代会尽可能的平均分配给每个线程每个线程 typetype为为staticstatic,循环被分成大小为,循环被分成大小为 chunkchunk的块

23、,静态分的块,静态分配给线程配给线程 typetype为为dynamic,dynamic,循环被动态划分为大小为循环被动态划分为大小为chunkchunk的块,的块,动态分配给线程动态分配给线程2023/1/1421国家高性能计算中心(合肥)Sections编译制导语句 sectionssections编译制导语句指定内部的代码被划分给线程组编译制导语句指定内部的代码被划分给线程组中的各线程中的各线程 不同的不同的sectionsection由不同的线程执行由不同的线程执行 SectionSection语句格式:语句格式:#pragmapragma ompomp sections sectio

24、ns clause,clauseclause,clause newlinenewline#pragmapragma ompomp section section newlinenewline#pragmapragma ompomp section section newlinenewline 2023/1/1422国家高性能计算中心(合肥)Sections编译制导语句 clause=clause=private(list)private(list)firstprivatefirstprivate(list)(list)lastprivatelastprivate(list)(list)redu

25、ction(operator:list)reduction(operator:list)nowaitnowait 在在sectionssections语句结束处有一个隐含的路障,使用了语句结束处有一个隐含的路障,使用了nowaitnowait子句除外子句除外2023/1/1423国家高性能计算中心(合肥)Sections编译制导语句#include#include#define N 1000#define N 1000intint main()main()intint i;i;float float aNaN,bNbN,cNcN;/*Some initializations*/*Some in

26、itializations*/for(i=0;i N;i+)for(i=0;i N;i+)aiai=bibi=i*1.0;=i*1.0;#pragma#pragma ompomp parallel parallel shared(a,b,cshared(a,b,c)private(iprivate(i)#pragmapragma ompomp sections sections nowaitnowait#pragmapragma ompomp section section for(i=0;i N/2;i+)for(i=0;i N/2;i+)cici=aiai+bibi;#pragmaprag

27、ma ompomp section section for(i=N/2;i N;i+)for(i=N/2;i N;i+)cici=aiai+bibi;/*end of sections*/*end of sections*/*end of parallel section*/*end of parallel section*/2023/1/1424国家高性能计算中心(合肥)single编译制导语句 singlesingle编译制导语句指定内部代码只有线程组中的一个编译制导语句指定内部代码只有线程组中的一个线程执行。线程执行。线程组中没有执行线程组中没有执行singlesingle语句的线程会一

28、直等待代码块语句的线程会一直等待代码块的结束,使用的结束,使用nowaitnowait子句除外子句除外 语句格式:语句格式:#pragmapragma ompomp single single clause,clauseclause,clause newlinenewline clause=clause=private(listprivate(list)firstprivate(listfirstprivate(list)nowaitnowait2023/1/1425国家高性能计算中心(合肥)组合的并行共享任务结构 parallel forparallel for编译制导语句编译制导语句 pa

29、rallel sectionsparallel sections编译制导语句编译制导语句2023/1/1426国家高性能计算中心(合肥)parallel for编译制导语句编译制导语句 Parallel forParallel for编译制导语句表明一个并行域包含一个独编译制导语句表明一个并行域包含一个独立的立的forfor语句语句 语句格式语句格式#pragmapragma ompomp parallel for clause parallel for clause newlinenewline clause=clause=if(if(scalar_logical_expressionsca

30、lar_logical_expression)default(shared|none)default(shared|none)schedule(type,chunk)schedule(type,chunk)shared(list)shared(list)private(list)private(list)firstprivatefirstprivate(list)(list)lastprivatelastprivate(list)(list)reduction(operator:list)reduction(operator:list)copyincopyin(list)(list)2023/

31、1/1427国家高性能计算中心(合肥)parallel for编译制导语句编译制导语句#include#include#define N 1000#define N 1000#define CHUNKSIZE 100#define CHUNKSIZE 100intint main()main()intint i,chunk;i,chunk;float float aNaN,bNbN,cNcN;/*Some initializations*/*Some initializations*/for(i=0;i N;i+)for(i=0;i N;i+)aiai=bibi=i*1.0;=i*1.0;ch

32、unk=CHUNKSIZE;chunk=CHUNKSIZE;#pragmapragma ompomp parallel for parallel for shared(a,b,c,chunkshared(a,b,c,chunk)private(iprivate(i)schedule(static,chunkschedule(static,chunk)for(i=0;i n;i+)for(i=0;i n;i+)cici=aiai+bibi;2023/1/1428国家高性能计算中心(合肥)parallel sections编译制导语句编译制导语句 parallel sectionsparallel

33、 sections编译制导语句表明一个并行域包含单编译制导语句表明一个并行域包含单独的一个独的一个sectionssections语句语句 语句格式语句格式#pragmapragma ompomp parallel sections clause parallel sections clause newlinenewline clause=clause=default(shared|none)default(shared|none)shared(list)shared(list)private(list)private(list)firstprivatefirstprivate(list)(l

34、ist)lastprivatelastprivate(list)(list)reduction(operator:list)reduction(operator:list)copyincopyin(list)(list)ordered ordered 2023/1/1429国家高性能计算中心(合肥)同步结构 master master 制导语句制导语句 criticalcritical制导语句制导语句 barrierbarrier制导语句制导语句 atomicatomic制导语句制导语句 flushflush制导语句制导语句 orderedordered制导语句制导语句2023/1/1430国

35、家高性能计算中心(合肥)master 制导语句制导语句 mastermaster制导语句指定代码段只有主线程执行制导语句指定代码段只有主线程执行 语句格式语句格式#pragmapragma ompomp master master newlinenewline 2023/1/1431国家高性能计算中心(合肥)critical制导语句制导语句 criticalcritical制导语句表明域中的代码一次只能执行一个线制导语句表明域中的代码一次只能执行一个线程程 其他线程被阻塞在临界区其他线程被阻塞在临界区 语句格式:语句格式:#pragmapragma ompomp critical name c

36、ritical name newlinenewline 2023/1/1432国家高性能计算中心(合肥)critical制导语句制导语句#include#include main()main()intint x;x;x=0;x=0;#pragma#pragma ompomp parallel parallel shared(xshared(x)#pragmapragma ompomp critical critical x=x+1;x=x+1;/*end of parallel section*/*end of parallel section*/2023/1/1433国家高性能计算中心(合肥

37、)barrier制导语句制导语句 barrierbarrier制导语句用来同步一个线程组中所有的线程制导语句用来同步一个线程组中所有的线程 先到达的线程在此阻塞,等待其他线程先到达的线程在此阻塞,等待其他线程 barrierbarrier语句最小代码必须是一个结构化的块语句最小代码必须是一个结构化的块 语句格式语句格式#pragmapragma ompomp barrier barrier newlinenewline2023/1/1434国家高性能计算中心(合肥)barrier制导语句制导语句错误正确if(x=0)#pragma omp barrierif(x=0)#pragma omp b

38、arrier barrierbarrier正确与错误使用比较正确与错误使用比较2023/1/1435国家高性能计算中心(合肥)atomic制导语句制导语句 atomicatomic制导语句指定特定的存储单元将被原子更新制导语句指定特定的存储单元将被原子更新 语句格式语句格式#pragmapragma ompomp atomic atomic newlinenewline atomicatomic使用的格式使用的格式x x binopbinop=exprexpr x+x+x+x x-x-x-x x x是一个标量是一个标量exprexpr是一个不含对是一个不含对x x引用的标量表达式,且不被重载引

39、用的标量表达式,且不被重载binopbinop是是+,*,-,/,&,|,or,or之一,且不被重载之一,且不被重载2023/1/1436国家高性能计算中心(合肥)flush制导语句制导语句 flushflush制导语句用以标识一个同步点,用以确保所有的制导语句用以标识一个同步点,用以确保所有的线程看到一致的存储器视图线程看到一致的存储器视图 语句格式语句格式#pragmapragma ompomp flush(list)flush(list)newlinenewline flushflush将在下面几种情形下隐含运行,将在下面几种情形下隐含运行,nowaitnowait子句除外子句除外bar

40、rierbarriercritical:critical:进入与退出部分进入与退出部分ordered:ordered:进入与退出部分进入与退出部分parallel:parallel:退出部分退出部分for:for:退出部分退出部分sections:sections:退出部分退出部分single:single:退出部分退出部分2023/1/1437国家高性能计算中心(合肥)ordered制导语句制导语句 orderedordered制导语句指出其所包含循环的执行制导语句指出其所包含循环的执行 任何时候只能有一个线程执行被任何时候只能有一个线程执行被orderedordered所限定部分所限定部分

41、 只能出现在只能出现在forfor或者或者parallel forparallel for语句的动态范围中语句的动态范围中 语句格式:语句格式:#pragmapragma ompomp ordered ordered newlinenewline 2023/1/1438国家高性能计算中心(合肥)threadprivate编译制导语句 threadprivatethreadprivate语句使一个全局文件作用域的变量在并语句使一个全局文件作用域的变量在并行域内变成每个线程私有行域内变成每个线程私有 每个线程对该变量复制一份私有拷贝每个线程对该变量复制一份私有拷贝 语句格式语句格式:#pragma

42、pragma ompomp threadprivatethreadprivate(list)(list)newlinenewline2023/1/1439国家高性能计算中心(合肥)threadprivate编译制导语句intint alpha10,beta10,i;alpha10,beta10,i;#pragmapragma ompomp threadprivate(alphathreadprivate(alpha)intint main()main()/*First parallel region*/*First parallel region*/#pragmapragma ompomp p

43、arallel parallel private(i,betaprivate(i,beta)for(i=0;i 10;i+)for(i=0;i 10;i+)alphaialphai=betaibetai=i;=i;/*Second parallel region*/*Second parallel region*/#pragmapragma ompomp parallel parallel printf(alpha3=%d and beta3=%dn,alpha3,beta3);printf(alpha3=%d and beta3=%dn,alpha3,beta3);2023/1/1440国家

44、高性能计算中心(合肥)数据域属性子句 变量作用域范围变量作用域范围 数据域属性子句数据域属性子句 privateprivate子句子句 sharedshared子句子句 defaultdefault子句子句 firstprivatefirstprivate子句子句 lastprivatelastprivate子句子句 copyincopyin子句子句 reductionreduction子句子句2023/1/1441国家高性能计算中心(合肥)private子句子句 privateprivate子句表示它列出的变量对于每个线程是局部的子句表示它列出的变量对于每个线程是局部的 。语句格式语句格式

45、private(listprivate(list)privateprivate和和threadprivatethreadprivate区别区别PRIVATETHREADPRIVATE数据类型变量变量位置在域的开始或共享任务单元在块或整个文件区域的例程的定义上持久么否是扩充性只是词法的-除非有个子程序动态的初始化使用 FIRSTPRIVATE使用 COPYIN2023/1/1442国家高性能计算中心(合肥)shared子句子句 sharedshared子句表示它所列出的变量被线程组中所有的线子句表示它所列出的变量被线程组中所有的线程共享程共享 所有线程都能对它进行读写访问所有线程都能对它进行读写

46、访问 语句格式语句格式 shared(list)shared(list)2023/1/1443国家高性能计算中心(合肥)default子句子句 defaultdefault子句让用户自行规定在一个并行域的静态范围子句让用户自行规定在一个并行域的静态范围中所定义的变量的缺省作用范围中所定义的变量的缺省作用范围 语句格式语句格式 default(shared|none)default(shared|none)2023/1/1444国家高性能计算中心(合肥)firstprivate子句子句 firstprivatefirstprivate子句是子句是privateprivate子句的超集子句的超集

47、对变量做原子初始化对变量做原子初始化 语句格式:语句格式:firstprivatefirstprivate(list)(list)2023/1/1445国家高性能计算中心(合肥)lastprivate子句子句 lastprivatelastprivate子句是子句是privateprivate子句的超集子句的超集 将变量从最后的循环迭代或段复制给原始的变量将变量从最后的循环迭代或段复制给原始的变量 语句格式语句格式 lastprivatelastprivate(list)(list)2023/1/1446国家高性能计算中心(合肥)copyin子句子句 copyincopyin子句用来为线程组中

48、所有线程的子句用来为线程组中所有线程的threadprivatethreadprivate变量赋相同的值变量赋相同的值 主线程该变量的值作为初始值主线程该变量的值作为初始值 语句格式语句格式 copyin(listcopyin(list)2023/1/1447国家高性能计算中心(合肥)reduction子句子句 reductionreduction子句使用指定的操作对其列表中出现的变量子句使用指定的操作对其列表中出现的变量进行规约进行规约 初始时,每个线程都保留一份私有拷贝初始时,每个线程都保留一份私有拷贝 在结构尾部根据指定的操作对线程中的相应变量进行规在结构尾部根据指定的操作对线程中的相应

49、变量进行规约,并更新改变量的全局值约,并更新改变量的全局值 语句格式语句格式 reduction(operator:list)reduction(operator:list)2023/1/1448国家高性能计算中心(合肥)reduction子句子句#include#include intint main()main()intint i,n,chunk;i,n,chunk;float a100,b100,result;float a100,b100,result;/*Some initializations*/*Some initializations*/n=100;n=100;chunk=10

50、;chunk=10;result=0.0;result=0.0;for(i=0;i n;i+)for(i=0;i n;i+)aiai=i*1.0;=i*1.0;bibi=i*2.0;=i*2.0;#pragmapragma ompomp parallel for parallel for default(shareddefault(shared)private(iprivate(i)schedule(static,chunkschedule(static,chunk)reduction(+:resultreduction(+:result)for(i=0;i n;i+)for(i=0;i n;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com