当前位置: 首页 > news >正文 去国外网站开发客户中的contact us 没有邮箱西安的互联网营销公司 news 2025/10/23 0:54:28 去国外网站开发客户中的contact us 没有邮箱,西安的互联网营销公司,东莞专业网站建设,wordpress页面分类插件目录 前言0. 简述1. 串行处理与并行处理的区别2. 并行执行3. 容易混淆的几个概念4. 常见的并行处理总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》#xff0c;链接。记录下个人学习笔记#xff0c;仅供自己参考 本次课程我们来学习下课程第一章——并行处… 目录 前言0. 简述1. 串行处理与并行处理的区别2. 并行执行3. 容易混淆的几个概念4. 常见的并行处理总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》链接。记录下个人学习笔记仅供自己参考 本次课程我们来学习下课程第一章——并行处理与GPU体系架构一起来理解并行处理相关概念 课程大纲可以看下面的思维导图 0. 简述 本小节目标理解并行处理的基本概念理解 SIMD以及编程中常见的并行处理方式 这节课我们来学习第一章的第 1 小节理解并行处理第一章节内容偏基础但相关知识在后面很多章节中都会涉及到。那我们为什么要讲并行处理和 GPU 体系架构呢这是因为大家在用 tensorRT 做模型部署的时候其实不光是使用它的 API 把模型转换成推理引擎放到 GPU 上跑就行了这个是远远不够的 我们还需要考虑很多其它的东西比如说你的模型的推理引擎有没有充分的利用 GPU 资源有没有把 CUDA Core、Tensor Core 都利用起来模型的计算密度是多少模型的可并行性是多少有没有充分利用 GPU 资源去做并行化等等那这些其实就是我们在做模型部署的时候需要考虑的所以作为一个基础内容我们会给大家展开去讲第一章节 第一章节的内容可能很多人在大学听到过一些类似的知识那大家作为复习听一下就好了。第一章节我们分为三个部分讲解第一部分是并行处理的简介第二部分是 GPU 并行处理第三部分是 GPU 体系架构 我们先来看第一部分并行处理的简介希望大家在学完这部分后能够去理解并行处理的一些基本概念比如说理解什么叫 SIMD还有在 C 编程中常用的并行处理方式都有哪些 1. 串行处理与并行处理的区别 OK我们在讲并行处理之前我们需要去想它和串行处理的区别是什么串行处理Sequential processing其实就是指令或者代码块必须是依次执行的也就是说你前面一条指令需要执行结束之后才能够执行下面一条语句 我们来看两个例子 a b c; // BB1 d b a; // BB2我们先看第一个例子这是两个赋值语句第一句我们叫 BB1Basic Block 1第二个语句是 BB2Basic Block 2我们可以看到 BB2 语句中的 a 需要利用前面 BB1 语句的结果 a这就是一个很典型的 data dependency 数据依赖的程序像这种程序我们必须依次执行 BB1 和 BB2如果颠倒的话这个程序的结果就不一样了这种情况下我们就必须要串行处理 if(a b){ // COND3c d; // BB4 }else{c e; // BB5 }我们再看第二个例子这是一个很简单的分支程序我们把它分成三个部分第一个部分是 COND3 也就是条件语句如果 ab 条件成立则执行 BB4如果不成立则执行 BB5这个其实也是必须要串行执行的为什么呢因为我们编译器在执行的时候我们不知道选择执行哪个语句我们得需要知道 COND3 的结果才能够去执行 BB4 或者 BB5所以这个也是有依赖的 所以总结来说就是当我们程序如果有一些依赖或者分支的地方这些情况下必须让其进行串行这里稍微给大家扩展一下大家可能听过数据依赖其实有很多种类我们第一个例子是 flow dependency此外还有 Anti dependency、Output dependency、Control Dependency大家感兴趣的可以自行查阅相关资料这个在编译器做优化的时候其实还是很重要的东西 所以说我们串行程序它其实就是依次执行的一个程序它的使用场景也是比较擅长去处理一些比较复杂的逻辑计算比如大家在打开一个操作系统Windows、Linux、Mac的时候它内部是有很多复杂的逻辑运算的很多地方是需要串行执行 我们这里拿一个程序给大家去讲解一下我们把这个程序给稍微抽象化它有 5 个语句statement1 到 statement5如下图所示 我们的 statement 语句它有可能是复制语句也有可能是条件语句也有可能是循环还有可能是一个 I/O。我们给这个程序设置几个条件 statement2 依赖于 statement1statement5 依赖于 statement4statement3 是一个循环跟所有的 statement 没有任何关系有四个 core 可以使用时钟周期 statement1 和 statement2 需要 5 个时钟周期statement4 和 statement5 需要 8 个时钟周期statement3 需要 20 个时钟周期 那如果我们程序是按照上图串行执行它的时钟周期就是 46 个 cycle这个实在太慢了。我们既然有四个 core那我们可以去想想充分利用这些 core 去把程序并行化 因此我们第一个策略如下图所示 前面我们提到 2 和 1 是有依赖的5 和 4 是有依赖的3 是独立的那这三个部分是不是可以分别分配到不同的 core 去执行呢把 1 和 2 分配到一个 core把 4 跟 5 分配到一个 core把 3 分配到一个 core这三个部分同时去执行这样做其实对程序的运行结果没有任何影响而它的时钟周期却只用了 20 个 cycle 我们继续优化20 个 cycle 还是有点长上面 20 个 cycle 中具有支配性的语句是 statement3它是一个 for 循环我们是不是有一些其它的策略可以给它做优化呢 我们说 statement3 这个循环可以分割成很多个子代码也就是子循环每一个子代码块只要 5 个 cycle 就能执行完那 statement3 就可以按照上图的分配方式分配四个子代码块分别是 3-1、3-2、3-3、3-4而刚好我们之前只用了三个 core还有一个没用我们现在就可以把空余的 core 给利用起来把 3-3 和 3-4 放到另外一个 core 上让它去执行那此时的执行时间就从 20 个 cycle 减少到了 16 个 cycle 那我们接着看还能不能优化呢现在具有支配性的语句是 statement4 和 statement5我们来看看这个能不能去优化。我们再给定一个假设条件就是说 statement5 可以在 statement4 彻底结束之前就知道它所依赖的结果也就是说 statement4 执行到中间环节的时候就已经把 statement5 所依赖的数据写回到寄存器或者写回到内存中后面做的事情就跟 statement5 没有任何关系的那也就意味着我们可以把 statement5 的执行时间往前调一点如下图所示 这样的话我们 16 个 cycle 的时钟周期又能减少到 14 个 OK我们来回顾一下这个程序串行执行的时间一共是 46 个 cycle我们进行了很多优化最终变成了 14 个 cycle大概优化速度提升 3.5 倍左右我们目前为止做的优化如下 把没有数据依赖的代码分配到各个 core 各自执行schedule调度把一个大的 loop 循环给分割成多个小代码分配到各个 core 执行loop optimization在一个指令彻底执行完之前如果已经得到了想要的数据可以提前执行下一个指令pipeline流水线 以上三个步骤其实只是并行处理中一个很简单的做法真正做并行处理的时候其实要做的优化还有很多我们管这一系列行为叫做 parallelization 并行化我们管这个可以利用多核多线程资源的程序叫做 parallelized program 并行程序 2. 并行执行 我们再回归正题这个 parallel processing 并行执行又是指什么呢它主要有以下几个特点 指令/代码块同时执行充分利用 multi-core 多核的特性多个 core 一起去完成一个或多个任务使用场景科学计算图像处理深度学习等等 并行执行中多个 core 会一起去完成一个或多个任务也就是说假设现在我们的 device 设备上有四个 core我们可以让这四个 core 一起去执行一个 for 循环我们把一个 for 循环分割成多个子块让每一个 core 去完成一个部分这个是完全 OK 的。或者我们程序很大时我们可以让每一个 core 去分别完成这个程序的各个小任务最终把每一个 core 的任务完成后我们再做一个同步处理那这个也是可以的。 串行执行是针对于复杂逻辑运算的而并行执行它非常擅长一些大规模的科学计算比如天体预测还有图像处理深度学习这些东西其实也是有很多并行处理的概念在里面 Multi-core processor 上图是一个 Multi-core processor 多核处理器的架构我们简单讲下这个是偏计算机硬件的东西从图中可以看到我们首先有一个 main memory 主存主存上面有一个 L3 缓存之后还有很多寄存器那寄存器上面有很多 core这些都是硬件层面的东西。在硬件之上我们会有一个自己的操作系统然后在操作系统上有很多程序也就是图中的 app 1、app 2 这些东西 说到并行处理其实我们在做程序并行化的时候大部分时间处理的主要还是 loop 循环这是因为我们发现执行时间长的程序耗时主要集中在两个方面一个是 I/O 的内存读写另一个就是 loop 的循环 I/O 的内存读写我们先抛开不谈因为这里可扩展性的东西太多了我们主要讲针对 loop 的并行处理那 loop 的并行其实是一个很重要也是很热门的一个课题到目前为止已经有很多学者做了一些优化也发表了很多论文在图像处理还有深度学习中其实很多地方都用到了循环比如我们在做分类任务时我们把图片放到深度学习模型之前需要对这个图像进行预处理包括 resize 到模型能接受的范围比如 256x256包括通道切换比如 bgr2rgb包括归一化比如 /255.0 等等那这些都是需要用到循环的。还有我们在深度学习模型内部的一些卷积层或者全连接层这里面其实也是要涉及到并行处理的 那这里我们以一个比较经典的 loop parallelization 为例给大家去讲解一下 CPU 里面是怎么对 loop 进行优化的我们这里拿一个 4x4 的二维矩阵来进行一个讲解默认来说它的一个遍历方式是 row major 行为主它是先把一行的数据全遍历完之后再去遍历下一行 值得注意的是不同的编程语言它的遍历方式是不一样的或者准确来说它的数据二维数组在内存里面的存储方式是不一样的比如大家经常使用的 C、C、C# 这些语言的二维数组是以 row major 的方式进行存储的所以我们也推荐在遍历的时候以 row major 进行遍历但是有一些语言比如说 MatLab、R 这些语言的二维数组在内存中的存储方式其实是 column major 的 所以说针对不同语言如果它默认存储方式是不同的话那么也就意味着我们在进行优化的时候它对于 Reordering 的方式也是不同的比如说对于 MatLab 语言它存储方式默认是 column 的但是你的编程代码里面如果遍历方式是 row major 的话那我们可以把它修改成一个 column major 的遍历方式去完美的匹配它的一个存储方式从而减少你的 cache miss 这个怎么理解呢就是我们在 CPU 进行程序优化的时候其实我们需要考虑如何尽量去减少你的一个 cache miss比如存储数据的时候你需要考虑它的一些空间连续性或者时间连续性比如一个元素访问到之后它旁边的元素其实也很容易很大几率被访存所以你把这一列的数据全都放一起访存的话一起去放到 memory 里面去访存的话其实它是可以减少你的 cache miss当然再强调一遍不同语言它的 reordering 的方式是不同的 第二个是 Vectorization 标量化我们之前矩阵元素的遍历是一个个去遍历的但是只要我们的指令集支持或者我们的寄存器支持的话我们其实是可以让它四个元素一起去访问的甚至说 16 个元素32 个元素一起去访问这个也是完全 OK 的只要我们硬件支持相比于我们原本一个个元素去访问而言速度提升了很多 那下一个 Tiling这个技术也是很重要的如果说我们有一个 4x4 的数组我们把它分割成四个 2x2 的数组的话我们是不是可以每一个元素每一个小部分都进行遍历呢也就是每个部分独立的遍历或者独立的计算这个是完全 OK 的。那如果说我们可以分割成四个小部分那也就是意味着我们四个小部分它们的计算遍历等等其实是完全可以并行化的 这里我们给大家举了几个例子其实只是 loop parallelization 中很小的一部分但是也是现在很常用的一些方式比如这里的 Vectorization、Tiling 这些技术其实不光光在 CPU 里面会使用其实在 GPU 的一些设计模式里面也完美的体现出来了这几个 loop 的优化我们后面再给大家详细去讲现在大家理解一下就好了 Bilinear interpolation(双线性插值) 那在涉及到一些 DNN 或者图像处理的时候也有一些比较常见的并行处理的例子比如说双线性插值我们在 resize 的时候会用到用周围四个点的坐标值去计算中间点 P 值时也是可以做并行化的因为一张图像有多个像素值resize 时很多像素值都需要像这样进行计算插值那这些执行其实是完全可以并行化的因为我们在做某一部分的插值计算时并不会说依赖于它相邻的那一块区域的计算它是完全可以去并行处理的 Convolution layer(卷积层) 那同样的卷积也是一样的针对 5x5 的一个 input tensort 而言用一个 3x3 的 kernel 进行卷积那这个卷积的过程也是可以并行化的通过滑动窗口我们一共需要滑动 9 次做 9 次计算但是这 9 次的计算中我们并没有说哪一个部分一定是依赖于另外一个部分的所以说我们这 9 个部分它其实是完全可以并行化执行的 Fully connected layer(全连接层) 同样的全连接层也是一样的可以看到 input tensor 有 9 个元素你的输出的 tensor 它一共有 A、B、C、D 四个元素我们在做计算 A 的这个过程它其实跟计算 B 的过程是没有任何依赖性的那就是说计算 A、计算 B、计算 C、计算 D它们这四个计算过程也是可以完全并行化的 3. 容易混淆的几个概念 我们讲了这么多并行处理我们先稍微停一下我们去讲一下大家在学习的过程中容易混淆的几个概念首先第一个就是并行和并发这两个词还是很像的但在英语中这两个单词是完全不一样的一个是 parallel 并行物理意义上同时执行一个是 concurrent 并发逻辑意义上同时执行 我们先说并发并发是什么呢并发它是逻辑意义上的同时执行那什么叫逻辑意义呢我们来看下面的例子 concurrency(并发) 现在我们只有一个 CPU我们要让它去执行两个 task我们先让它执行 task1当 task1 执行到一半的时候我们切换到 task2把 task2 做完一半后我们继续回到之前做 task1之后我们再做 task2这样一个 CPU 来切换的去做两个 task但是实际上这个切换 task1 和 task2 的速度是非常非常快的我们肉眼是无法识别的所以我们能够感觉到这个 CPU 它是在同时做两个任务那这个就是并发逻辑意义上的同时执行 parallel(并行) 那我们再说并行并行它就是物理意义上的同时执行也就是说现在我们手上的 CPU 很多我们有两个 CPU我们让这两个 CPU 分别处理 task1 和 task2并且让这两个 CPU 同时去执行这个就是物理意义上的同时执行这个就是 parallel 我们这个课程主要还是以并行处理为主并发其实在做编译器的时候大家可能会用到这个概念但是做 GPU、CUDA 的话还是用并行处理 那么还有一个容易混淆的概念就是进程和线程线程它是进程的一个子集一个进程它可以有很多个线程我们以一个例子来讲解我们打开操作系统之后我们去打开一个小程序那其实在打开小程序的过程中操作系统为这个程序已经分配了一个进程但是这个小程序它其实运行的速度可能会很慢那么我们就可以把这个小程序的这个进程再给它分配很多个小的线程去分别完成这个程序中的各个部分这个是并行处理的一个解决方案也就是进程和线程的关系 那另外一个就是多核和加速比的关系这个也是大家容易混淆的一个概念双核它的加速不一定就是两倍比如我们只有一个核去处理一个程序那么这个程序它的执行时间是 2ms那么如果说我们现在有两个核去同时处理这个程序那是不是这个程序的时间就会由 2ms 变成 1ms 呢其实并不是的我们这里以 Amdahl’s Law 来进行讲解 这是一个非常经典的图也是在做并行处理中经常会遇到的一个图横轴是处理器的个数纵轴是加速比我们可以看到核个数和加速比并不是成线性增长的它到了一定程度之后它这个加速比其实就饱和了就不会再继续增长了。也就是说我们在做并行处理的时候其实我们有很多限制因素在里面 比如说我们回到之前的例子我们看这里面 statement3 这个 for 循环我们可以分割这个是完全 OK 的但是 1 和 24 和 5 它们之间存在依赖关系那如果有依赖关系的话我们再怎么做并行我们也不能够让 4 和 5 一起去执行也不能让 1 和 2 并行执行其实这个就是一个强制性的约束力就是程序再怎么并行还是有个上限的 同时我们从图中还能看到 8 核的加速比有的时候也会差于 4 核也就是说我们有的时候核越多其实并不是效率会越高为什么呢因为我们在做加速的时候其实还是需要考虑它的数据传输一些偏内存的读写数据传输这个方面所消耗的时间也是需要去考虑的 4. 常见的并行处理 我们讲现在常用的并行处理方式都有哪些呢刚才给大家稍微提了一下并行处理自古以来都是一个非常非常热门的话题有很多种方式这里我们简单举几个例子 编译器自动化并行优化 GCCLLVMTVM… 针对 for 循环的并行优化 tilefusesplitvectorization… 计算图优化 CFGHTGMTG… 数据流 Dataflow compilerDataflow architecture Polyhedral Polyhedral compiler HPC High performance computing … 首先编译器它就有很多自动化并行优化的一些方式大家比较常见的 GCC、G它里面有很多自动并行优化的一些策略还有做编译器的人可能经常听到的 LLVM它们也有很多这种优化策略还是大家做深度学习的编译器的时候模型部署的时候可能会经常听到 TVM 这个东西它是针对深度学习模型 DNN 模型的一个编译器这个里面也有很多自动化并行优化策略在里面 那我们还有很多针对 for 循环的并行优化这个是一个很热门的话题比如说 tilefusesplitvectorization 等等到目前为止已经是很成熟的技术了有很多地方都在用。 还有计算图优化这个跟大家经常听到的 pytorch 或者是 tensorflow 里面的计算图是不一样的我们可以把它理解为像是一个程序的流程图一样就是 CFG、HTG、MTG 等等这些都是 graph我们针对这个程序的这个 graph 来进行优化这个也是并行处理的一个方式 我们还有数据流这个也是一个很老的概念了我们有针对 Dataflow 的一个编译器也有人在做 Dataflow 的硬件研发这个还是挺常见的现在很多 DNN 的模型有很多硬件厂商会去把它制作成一个 Dataflow 的数据流的硬件那大家感兴趣的可以查阅一下相关资料。 还有 Polyhedral可以有针对 Polyhedral 这个编译器的开发还有包括 HPC 超大规模计算的一些并行优化 总的来讲并行处理其实是一个很大的课题很多人都在做那我们这门课程的 TensorRT 我们可以把它理解为一个编译器把一个模型输入到 TensorRT 里面给它做各种优化优化成一个推理引擎能够放到硬件上最优化你程序的执行时间 我们这门课程要讲 TensorRT要讲 CUDA 编程的话我们不得不提 SIMD 这个东西因为太重要的SIMD 全称 Single Instruction Multiple Data 也就是说我们同一条指令去执行多个数据这个怎么理解那我们先看一个简单的例子 我们现在要做一个乘法运算A1 乘以 B1 赋值给 C1同样我们还有 A2、B2、C2A3、B3、C3A4、B4、C4那么我们这个过程其实在编译的时候计算机需要处理的事情还挺多的我们得需要先取指令我们读取数据还得做计算再写回数据这是针对一个针对其它几个也是同样的操作也就是这些同样的操作我们需要重复四次那这是不是非常麻烦呢 OK那针对这个我们其实有一个优化策略如下图所示 我们把 A1、A2、A3、A4 放在一起B1、B2、B3、B4 也放在一起C1、C2、C3、C4 也是一样的那么这是不是也就意味着我们只需要读取一次数据计算一次乘法写回一次数据就行了这个其实是可以的我们管这种操作方式叫做 SIMD operation它前面一个个取数据的操作方式我们叫 Scale operation这个在编译器中也是比较常见的概念 在 CUDA 编程与 TensorRT 中以及 NVIDIA 在做 tensor core 的设计理念中都存在着 SIMD 我们从 NVIDIA 的官网中看 Tensor Core 的介绍它很擅长去做 4x4 矩阵的乘加法运算也就是图中的 DAxBC如果我们依次去执行的话要执行 16 次非常麻烦Tensor Core 的设计理念就是允许多个数据放在一起去执行快速计算 AxBC接下来的课程去针对 GPU 的体系架构我们会稍微扩展去讲一下这个是很重要也是很核心的一个东西 值得注意的是准确来说在 CUDA 编程中它其实使用的并不是 SIMD 而是 SIMTSingle Instruction Multiple Thread不再是多数据而是多线程CUDA 编程中线程是一个很重要的概念也就是说它会去充分利用它的多核资源去进行多线程化用多线程化去把一个卷积操作矩阵乘法操作这些东西进行优化处理SIMT 和 SIMD 很像它是 SIMD 的一个高级版这个接下来我们也会再结合 CUDA 编程去讲 那最后我们去给大家稍微介绍一下比较常见的并行处理方式 CPU 上的并行处理 OpenMPpthreadMPIHalide应用场景图像预处理/后处理Multi-task 模型 GPU 上的并行处理 CUDA programming应用场景DNN 优化 我们这里主要针对模型部署的一些常见的并行处理方式首先我们得先看我们并行处理的计算是要放到哪里去执行我们是直接放在 GPU 上呢还是放在 CPU 上如果是 GPU 上的化其实我们就用 CUDA 或者 TensorRT 是 OK 的它的应用场景也是针对 DNN 进行的优化策略那如果是放在 CPU 上的话其实我们有很多种选项我们可以选 OpenMP可以使用 pthread、MPI、Halide 等等 那大家大学期间如果上过 C 并行处理课程的话可能经常听到过 OpenMP这个还是比较老的概念了MPI 也是其实它这些东西就是你在程序中如果声明了一个代码块由 OpenMP 声明了代码块之后那么你的这个程序就是这一部分可以进行并行化它可以是指令级别的并行化也可以是代码块的并行化这个不是我们这门课程的重点就不展开讲了感兴趣的可以查阅下相关资料 那么在 CPU 上的并行处理它其实应用的场景主要是在图像的预处理和后处理上就是说需要我们把数据放在 GPU 上之前我们需要把这个图像给进行加工让它加工成模型可以识别的一个格式这个是在 CPU 上做的其实现在有很多为了让预处理和后处理进行加速也把它放在 GPU 上做这个也是有的 还有就是做 Multi Task 的一个模型也就是多任务模型如果说我们的模型它既有分割又有检测或者说我们有很多个分割我们让它并行处理的话其实也是可以用到这个 CPU 并行处理的概念直接 OpenMP 或者 pthread 做并行处理这个也是完全可以的 Heterogeneous Multicore Processor(异构架构) 那我们这里再稍微扩展一下就是我们刚才看到的图multicore processor 在多核处理器一般来说我们常见的就是同构架构就是一个处理器里面它们有很多 core它们的 core 其实都是一样的我们有一个 CPU Core1、CPU Core2、CPU Core3、CPU Core4。但是我们在异构架构里面它不光是只有一个种类的核如上图所示我们可以有 CPU Core也可以有 GPU Core还可以有 DSP Core也可以 Fast core就是这些 core 是相互结合相互联合起来去组成一个计算机硬件的 所以我们在做模型部署的时候其实我们要想的东西很多不光要去想这个东西是怎么能够在 GPU 上变快我们还得去想它的 CPU 和 GPU 之间的通信是什么样子的我们哪些地方可以放在 CPU 上去执行更快一点我们哪些地方可以放在 DSP 上去执行我们在做异步执行的时候怎么做等等这些也是在异构架构中经常需要涉及到的理念 OK以上就是第一部分的内容 总结 本次课程我们学习了并行处理的相关知识首先我们讲解了串行处理和并行处理的区别串行处理就是指令或代码必须依次执行常用于一些比较复杂的逻辑运算并行处理就是指令或代码块同时执行常用于科学计算图像处理等。之后我们讲解了 loop 循环优化的一些方案比如 Vectorization、Tiling 等等同时我们区分了几个容易混淆的概念包括并行/并发、进程/线程等。最好我们简单介绍了一些常见的并行处理方式重点是 SIMD 以及 CUDA 编程中非常重要的 SIMT。 OK以上就是第 1 小节有关并行处理的全部内容了下节我们来学习 GPU 并行处理的相关知识敬请期待 参考 Bilinear interpolationA guide to convolution arithmetic for deep learningFully Connected Layer vs. Convolutional Layer: ExplainedMulticore Processing 文章转载自: http://www.morning.yrgb.cn.gov.cn.yrgb.cn http://www.morning.ppdr.cn.gov.cn.ppdr.cn http://www.morning.rwyw.cn.gov.cn.rwyw.cn http://www.morning.mjgxl.cn.gov.cn.mjgxl.cn http://www.morning.dwkfx.cn.gov.cn.dwkfx.cn http://www.morning.mzydm.cn.gov.cn.mzydm.cn http://www.morning.smqjl.cn.gov.cn.smqjl.cn http://www.morning.trfrl.cn.gov.cn.trfrl.cn http://www.morning.wcqkp.cn.gov.cn.wcqkp.cn http://www.morning.fjlsfs.com.gov.cn.fjlsfs.com http://www.morning.wfyzs.cn.gov.cn.wfyzs.cn http://www.morning.kybpj.cn.gov.cn.kybpj.cn http://www.morning.gxtbn.cn.gov.cn.gxtbn.cn http://www.morning.fktlg.cn.gov.cn.fktlg.cn http://www.morning.cxlys.cn.gov.cn.cxlys.cn http://www.morning.stbfy.cn.gov.cn.stbfy.cn http://www.morning.wjhqd.cn.gov.cn.wjhqd.cn http://www.morning.lnwdh.cn.gov.cn.lnwdh.cn http://www.morning.lkfhk.cn.gov.cn.lkfhk.cn http://www.morning.sogou66.cn.gov.cn.sogou66.cn http://www.morning.ktcrr.cn.gov.cn.ktcrr.cn http://www.morning.skksz.cn.gov.cn.skksz.cn http://www.morning.fy974.cn.gov.cn.fy974.cn http://www.morning.mplb.cn.gov.cn.mplb.cn http://www.morning.mhfbf.cn.gov.cn.mhfbf.cn http://www.morning.ktmbr.cn.gov.cn.ktmbr.cn http://www.morning.chfxz.cn.gov.cn.chfxz.cn http://www.morning.bfkrf.cn.gov.cn.bfkrf.cn http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn http://www.morning.rhwty.cn.gov.cn.rhwty.cn http://www.morning.thzwj.cn.gov.cn.thzwj.cn http://www.morning.hzqjgas.com.gov.cn.hzqjgas.com http://www.morning.tzpqc.cn.gov.cn.tzpqc.cn http://www.morning.tkfnp.cn.gov.cn.tkfnp.cn http://www.morning.mlyq.cn.gov.cn.mlyq.cn http://www.morning.cjwkf.cn.gov.cn.cjwkf.cn http://www.morning.rfhwc.cn.gov.cn.rfhwc.cn http://www.morning.grynb.cn.gov.cn.grynb.cn http://www.morning.dtlqc.cn.gov.cn.dtlqc.cn http://www.morning.cthrb.cn.gov.cn.cthrb.cn http://www.morning.lbcfj.cn.gov.cn.lbcfj.cn http://www.morning.gypcr.cn.gov.cn.gypcr.cn http://www.morning.sfcfy.cn.gov.cn.sfcfy.cn http://www.morning.nmlpp.cn.gov.cn.nmlpp.cn http://www.morning.cpzkq.cn.gov.cn.cpzkq.cn http://www.morning.nqfxq.cn.gov.cn.nqfxq.cn http://www.morning.jcrlx.cn.gov.cn.jcrlx.cn http://www.morning.geledi.com.gov.cn.geledi.com http://www.morning.jwlmm.cn.gov.cn.jwlmm.cn http://www.morning.pwbps.cn.gov.cn.pwbps.cn http://www.morning.bpmfr.cn.gov.cn.bpmfr.cn http://www.morning.lxmmx.cn.gov.cn.lxmmx.cn http://www.morning.lsnhs.cn.gov.cn.lsnhs.cn http://www.morning.qxwwg.cn.gov.cn.qxwwg.cn http://www.morning.rpzqk.cn.gov.cn.rpzqk.cn http://www.morning.tkrwm.cn.gov.cn.tkrwm.cn http://www.morning.qmfhh.cn.gov.cn.qmfhh.cn http://www.morning.jhyfb.cn.gov.cn.jhyfb.cn http://www.morning.zxqqx.cn.gov.cn.zxqqx.cn http://www.morning.vtbtje.cn.gov.cn.vtbtje.cn http://www.morning.wqfzx.cn.gov.cn.wqfzx.cn http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.xylxm.cn.gov.cn.xylxm.cn http://www.morning.hmlpn.cn.gov.cn.hmlpn.cn http://www.morning.llqky.cn.gov.cn.llqky.cn http://www.morning.pkggl.cn.gov.cn.pkggl.cn http://www.morning.wblpn.cn.gov.cn.wblpn.cn http://www.morning.lysrt.cn.gov.cn.lysrt.cn http://www.morning.wkgyz.cn.gov.cn.wkgyz.cn http://www.morning.rtbx.cn.gov.cn.rtbx.cn http://www.morning.lhxkl.cn.gov.cn.lhxkl.cn http://www.morning.rwrn.cn.gov.cn.rwrn.cn http://www.morning.xq3nk42mvv.cn.gov.cn.xq3nk42mvv.cn http://www.morning.qpljg.cn.gov.cn.qpljg.cn http://www.morning.ssglh.cn.gov.cn.ssglh.cn http://www.morning.lkhfm.cn.gov.cn.lkhfm.cn http://www.morning.bnwlh.cn.gov.cn.bnwlh.cn http://www.morning.wgzgr.cn.gov.cn.wgzgr.cn http://www.morning.jcwt.cn.gov.cn.jcwt.cn http://www.morning.qrnbs.cn.gov.cn.qrnbs.cn 查看全文 http://www.tj-hxxt.cn/news/241132.html 相关文章: 做家教中介网站赚钱吗网站模板 wordpress带会员系统 山东坤泰建设集团网站网页转微信小程序 网站域名怎么买wordpress本地批量传文章 如何做自己的淘客网站苏州机械加工网 做餐饮培训网站广告昆山高端网站建设 南昌模板建站定制网站做网站gif代码 门户网站的细分模式有wordpress储存媒体插件 网站备案才能使用网站首页页面代码 东莞有哪些做网站做电影网站心得体会 做软件赚钱的网站有哪些网页设计作业可爱的家乡 腾讯云备案 网站名称大型网站建设就找兴田德润 梧州网站设计推荐广告联盟怎么接单 建立网站站点的过程购物网站如何备案 腾讯云服务器可以做网站网站设计制作步骤 com网站注册域名网站设计制作要多少钱 建设银行网站认证wordpress的编辑器插件 曲阜网站建设价格wordpress 知识库主题 微网站菜单绮思网站建设qswoo 制作网页的软件有淘宝怎么优化关键词步骤 做网站需要招什么职位wordpress内置采集插件 郑州优之客网站建设重庆网站推广流程 网站开发外文期刊网北京建设网站公司 网站换了服务器网站建设的公司服务 山东高端网站定制河南那家做网站实力强 用html框架做网站linux做网站用什么语言 盐城网站建设网站制作推广企业网站网上推广的途径 开发网站合同网站建设计划图 做网站有限公司网站建设工程师培训 郑州企业网站价格织梦网站怎么做索引地图 可信赖的网站建设案例设计工作室怎么找客户