泛型并行编程模型的比较_第1页
泛型并行编程模型的比较_第2页
泛型并行编程模型的比较_第3页
泛型并行编程模型的比较_第4页
泛型并行编程模型的比较_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1/1泛型并行编程模型的比较第一部分泛型并行编程模型概述 2第二部分任务并行与数据并行对比 4第三部分OpenMP模型的特性及应用 6第四部分MPI模型的通信机制分析 8第五部分MapReduce模型的分布式处理 12第六部分CUDA模型的GPU加速并行 14第七部分IntelTBB库的线程池管理 17第八部分不同模型在实际场景中的适用性 19

第一部分泛型并行编程模型概述关键词关键要点泛型并行编程模型概述

主题名称:并行编程范式

1.并行编程范式:包括共享内存、分布式内存和混合并行编程范式。

2.共享内存范式:多线程共享同一内存空间,通过同步机制协调线程访问。

3.分布式内存范式:每个处理器拥有自己的本地内存,通过消息传递机制进行通信。

主题名称:并行算法

泛型并行编程模型概述

泛型并行编程模型是一种编程范式,允许计算机科学家设计出可在不同类型的并行硬件(如多核处理器、图形处理器或专用并行处理器)上高效运行的并行程序。这些模型抽象了底层硬件的具体细节,使其适用于广泛的并行架构。

并行计算类型

泛型并行编程模型根据其并行性的类型进行分类:

*数据并行:操作大量并行数据,每个数据元素独立执行相同的操作。

*任务并行:将问题分解为较小的子任务,每个子任务作为一个独立的线程运行。

*混合并行:将数据并行和任务并行相结合,同时执行数据并行性和任务并行性。

并行编程模型

共享内存模型:

*共享地址空间(SAS)模型:所有处理单元共享一个全局地址空间,允许它们直接访问共享数据结构。

*全局地址空间(GAS)模型:类似于SAS模型,但处理单元通过消息传递进行通信。

分布式内存模型:

*分布式内存(DM)模型:每个处理单元拥有自己的私有内存,通过消息传递进行通信。

*消息传递接口(MPI)模型:一种分布式内存模型,用于在并行计算机集群上编程。

编程语言支持

各种编程语言都支持泛型并行编程,包括:

*OpenMP:面向共享内存系统,使用编译器指示进行并行化。

*MPI:面向分布式内存系统,使用消息传递API进行通信。

*CUDA:用于NVIDIA图形处理器,提供并行编程库和开发环境。

*OpenCL:一个跨平台的并行编程框架,支持各种并行设备。

选择合适的模型

选择最佳的泛型并行编程模型取决于应用程序的特性,例如:

*并行类型(数据并行、任务并行或混合并行)

*并行硬件类型(共享内存或分布式内存)

*编程语言支持

通过了解这些模型及其各自的优点,开发人员可以设计出在并行环境中高效运行的程序。第二部分任务并行与数据并行对比关键词关键要点任务并行与数据并行对比

主题名称:数据并行

1.每个处理元素执行相同的操作,但作用于不同的数据元素。

2.数据被分块并分配给不同的处理元素,每个处理元素负责处理自己的数据块。

3.适用于需要处理大量独立数据任务的情况,例如图像处理和数值模拟。

主题名称:任务并行

任务并行与数据并行对比

任务并行和数据并行是两种主要的并行编程模型。它们以不同的方式分解问题,并适合于不同的应用程序类型。

任务并行

在任务并行模型中,问题被分解为一组独立的任务,这些任务可以并行执行。每个任务都是一个独立的执行单元,可以由不同的线程或进程处理。任务并行适用于需要对问题中的独立元素进行操作的情况。

优点:

*简单且易于实现

*可扩展性好,可以轻松地添加更多的处理单元

*对于处理独立任务的应用程序非常有效

缺点:

*同步和通信开销可能很高,特别是对于细粒度的任务

*难以平衡任务负载,这会导致负载不均衡

数据并行

在数据并行模型中,问题被分解为一组数据元素,这些元素可以并行处理。每个处理单元接收相同的数据副本并执行相同的操作。数据并行适用于需要对大型数据集进行操作的情况。

优点:

*同步开销低,因为所有处理单元执行相同的操作

*负载平衡容易,因为数据在处理单元之间均匀分布

*适用于具有大数据集和简单操作的应用程序

缺点:

*难以实现,因为需要复制数据并协调处理单元

*可扩展性有限,因为数据大小可能会限制处理单元的数量

*不适合处理需要对数据元素进行不同操作的应用程序

比较

下表总结了任务并行和数据并行的关键差异:

|特征|任务并行|数据并行|

||||

|任务类型|独立|相同|

|数据处理|每个任务不同|每个处理单元相同|

|同步|高|低|

|负载平衡|困难|容易|

|可扩展性|好|受限|

|适用性|独立任务|大数据集|

选择合适的模型

选择正确的并行编程模型取决于应用程序的具体需求。如果应用程序包含独立的任务,则任务并行是一个好的选择。如果应用程序需要对大型数据集进行操作,则数据并行更合适。

混合模型

在某些情况下,可以使用混合模型来结合任务并行和数据并行的优势。例如,在处理大型数据集时,可以将数据并行用于对数据块进行操作,而任务并行用于并行处理块。第三部分OpenMP模型的特性及应用OpenMP模型的特性

OpenMP(OpenMulti-Processing)是一种共享内存并行编程模型,广泛应用于高性能计算中。它提供了一组编译器指令和库函数,用于在共享内存计算机上并行执行代码。OpenMP模型具有以下特性:

*基于指令的编程:与其他并行编程模型不同,OpenMP使用编译器指令来指定并行性。这些指令嵌入在串行代码中,引导编译器生成并行代码。

*层次化结构:OpenMP程序由主线程和并行线程组成。主线程创建并管理并行线程,而并行线程执行并行代码。

*显式共享内存:OpenMP程序使用共享内存模型,其中所有线程都可以访问相同的内存空间。这允许线程轻松地共享数据和同步操作。

*可移植性:OpenMP是一种可移植的编程模型,可以在支持OpenMP编译器的各种平台上使用。它由OpenMP标准组织(OSI)维护,确保其一致性和兼容性。

*易于编程:OpenMP使用熟悉的C/C++/Fortran语法,便于程序员编写并行代码。编译器处理并行化过程,无需进行复杂的低级编程。

*性能优化:OpenMP提供了对线程数量、数据分配和同步操作进行细粒度控制的功能。这使程序员能够优化程序的性能,使其充分利用底层硬件。

OpenMP模型的应用

OpenMP模型广泛应用于各种高性能计算领域,包括:

*科学计算:OpenMP用于并行化数值模拟、数据分析和机器学习算法等科学计算。

*工程模拟:OpenMP用于并行化流体动力学、结构分析和地震模拟等工程模拟。

*数据并行化:OpenMP用于加速数据密集型应用程序,例如图像处理、数据挖掘和金融建模。

*并行文本挖掘:OpenMP用于并行化文本挖掘任务,例如文本分类、主题建模和情感分析。

*高性能计算库:OpenMP用于并行化线性代数、傅里叶变换和随机数生成等高性能计算库。

OpenMP模型的优势

OpenMP模型在并行编程中具有以下优势:

*易于使用:基于编译器指令和库函数的编程方式简化了并行编程过程。

*可移植性:OpenMP是一种标准化的编程模型,可以在各种平台上使用。

*性能优化:提供了对并行化的细粒度控制,使程序员能够优化程序的性能。

OpenMP模型的局限性

尽管OpenMP模型有很多优势,但它也存在一些局限性:

*内存访问冲突:由于所有线程共享相同的内存空间,因此需要小心处理数据竞争和内存访问冲突。

*缺乏局部性:OpenMP模型假设所有线程都可以访问所有数据,这可能会导致较差的内存局部性,从而降低性能。

*可扩展性:OpenMP模型通常适用于共享内存计算机,在大规模并行系统上可扩展性有限。

总结

OpenMP模型是一种流行且高效的共享内存并行编程模型,被广泛用于高性能计算领域。其易用性、可移植性和性能优化功能使其成为开发并行应用程序的宝贵工具。但是,程序员需要注意内存访问冲突和局部性问题,以确保应用程序的正确性和效率。第四部分MPI模型的通信机制分析关键词关键要点MPI模型的通信拓扑结构

1.正交树形拓扑:采用树形结构,具有良好的可扩展性和低延迟,适用于大规模分布式系统。

2.环形拓扑:节点按环形连接,具有较低的网络直径,适合于中等规模分布式系统。

3.完全网格拓扑:节点之间完全互连,具有最小的通信延迟,但连接复杂、成本高,适用于小规模分布式系统。

MPI模型的消息传递机制

1.点对点通信:节点之间直接发送和接收消息,通信效率高,但需要维护节点间的路由表。

2.集体通信:所有节点参与的通信操作,例如广播、聚合和散射,具有良好的同步性和数据一致性。

3.非阻塞通信:允许节点在发送或接收消息后继续执行其他任务,提高了通信并行性,但增加了编程复杂性。

MPI模型的通信库支持

1.OpenMPI:广泛采用的开源MPI实现,提供跨多种平台的可移植性、高性能和可扩展性。

2.MVAPICH2:针对InfiniBand和以太网网络优化的MPI库,具有高吞吐量和低延迟。

3.IBMSpectrumMPI:专为IBMPowerSystems设计的MPI实现,提供与IBM并行文件系统等其他IBM产品的高集成度。

MPI模型的通信性能

1.通信延迟:消息从发送节点传递到接收节点所需的时间,受网络拓扑结构、消息大小等因素影响。

2.通信吞吐量:单位时间内可以传输的数据量,受网络带宽、消息速率等因素影响。

3.通信开销:与通信相关的额外时间和资源消耗,包括消息打包、解包、路由计算等。

MPI模型的编程模型

1.单程序多数据(SPMD):所有节点执行相同的代码,但具有不同的数据,适合于需要协作执行的任务。

2.多程序多数据(MPMD):每个节点执行不同的代码,协作解决同一问题,适用于需要分工合作的任务。

3.混合编程模型:结合SPMD和MPMD模型,利用单程序和多程序的优势,适合于复杂任务的并行化。

MPI模型的趋势和前沿

1.异构计算支持:利用不同类型的硬件(例如CPU、GPU、FPGA)加速通信和计算,提高性能。

2.网络感知通信:根据网络状况动态调整通信策略,优化通信性能。

3.可扩展性增强:探索新的通信拓扑结构和消息传递机制,实现大型分布式系统的可扩展性。MPI模型的通信机制分析

概述

MPI(消息传递接口)是一种标准化的通信库,用于在并行程序中实现分布式内存架构之间的通信。MPI定义了一组函数和数据类型,允许程序在不同进程之间交换数据,从而实现并行计算。

通信机制

MPI的通信机制基于点对点(P2P)通信模型。每个MPI进程都有一个唯一的标识符(MPI通信器),用于在进程之间建立通信通道。

基本通信操作

MPI提供以下基本通信操作:

*MPI_Send()和MPI_Recv():用于在进程之间发送和接收消息。

*MPI_Sendrecv():用于同时发送和接收消息,从而实现双向通信。

*MPI_Bcast():用于将数据从一个进程广播到所有其他进程。

*MPI_Gather()和MPI_Scatter():用于在多个进程之间收集或分散数据。

*MPI_Reduce():用于在多个进程之间执行并行归约操作,如求和或求最大值。

通信模式

MPI支持三种主要通信模式:

*阻塞模式:发送或接收操作不会立即返回,直到通信完成。

*非阻塞模式:发送或接收操作立即返回,进程可以在通信完成之前继续执行。

*同步模式:通信操作在所有进程之间同步进行,直到所有进程都完成操作。

拓扑结构

MPI允许进程分布在各种拓扑结构上,包括环形、网格和树形结构。拓扑结构可以影响通信效率,因为消息在不同拓扑结构上传播的路径和延迟可能不同。

集合通信

MPI提供了一组集合通信函数,用于优化特定通信模式的性能。这些函数利用拓扑结构和通信模式的知识,对通信操作进行优化。集合通信函数包括:

*MPI_Allgather():收集所有进程的数据并分布到所有进程。

*MPI_Allreduce():执行并行归约操作,并生成一个结果值。

*MPI_Alltoall():在所有进程之间交换数据。

通信性能

MPI通信性能受多种因素影响,包括:

*网络类型:以太网、InfiniBand或其他网络架构。

*拓扑结构:进程之间的物理连接方式。

*通信模式:消息大小、频率和同步模式。

*软件实现:MPI库的优化和实现。

优点

MPI模型的优点包括:

*标准化:MPI是一个广泛采用的通信标准,在多种平台上可用。

*可移植性:MPI程序可以在支持MPI库的任何平台上编译和执行。

*高性能:MPI库经过优化,可以实现高效的通信操作。

*可扩展性:MPI适用于小规模和大型并行系统。

缺点

MPI模型的缺点包括:

*编程复杂性:MPI程序涉及显式的通信操作,这可能会增加编程复杂性。

*超额开销:MPI通信操作涉及一定的开销,这可能会影响性能。

*调试难度:MPI程序的调试可能很复杂,尤其是对于错误发生在通信操作期间的情况。第五部分MapReduce模型的分布式处理关键词关键要点【MapReduce模型的分布式处理】:

1.并行化任务处理:MapReduce将计算任务分解成较小的单元,在分布式节点上并行执行,大大提高计算效率。

2.容错性和数据恢复:MapReduce框架提供容错机制,当节点发生故障时,会自动恢复任务,确保计算结果的准确性。

3.易于编程:MapReduce提供简单的编程模型,开发人员只需定义映射和规约函数,即可轻松实现分布式计算。

【分布式文件系统(HDFS)】:

MapReduce模型的分布式处理

MapReduce是一种流行的分布式计算编程模型,用于在海量数据集上并行处理复杂计算。其核心思想是将问题分解为两个阶段:Map阶段和Reduce阶段。

Map阶段

Map阶段将输入数据集划分为较小的区块,并将每个区块分配给集群中的一个工作节点。每个工作节点并行执行Map函数,将输入区块中的每个元素转换为新的键值对。这些键值对随后被打乱并分发到Reduce阶段。

Reduce阶段

Reduce阶段将Map阶段产生的键值对分组在一起,具有相同键的键值对被发送到相同的Reduce工作节点。Reduce函数对每个键执行聚合操作,生成最终结果。这些结果被收集并返回给客户端程序。

分布式处理的优势

MapReduce模型提供了分布式处理的诸多优势:

*可扩展性:MapReduce可以轻松地扩展到数百甚至数千个工作节点,从而处理海量数据集。

*容错性:MapReduce框架自动处理工作节点故障。如果一个工作节点失败,它的任务将被重新分配给其他工作节点。

*并行性:Map和Reduce阶段都是并行执行的,这大大提高了计算效率。

*容错性:MapReduce框架使用冗余和数据分片来确保数据的容错性。如果部分数据丢失或损坏,则可以从其他副本中恢复。

适用的场景

MapReduce模型特别适用于以下场景:

*大数据集处理:处理海量数据集,例如日志文件、web数据和科学实验数据。

*数据挖掘:从大型数据集(如社交媒体数据或交易记录)中提取有意义的见解。

*机器学习:训练大规模机器学习模型,例如神经网络和深度学习算法。

与其他分布式计算模型的比较

与其他分布式计算模型相比,MapReduce具有以下特点:

*简单易用:MapReduce模型的编程简单易懂,即使对于没有分布式计算经验的开发人员来说也是如此。

*高吞吐量:MapReduce非常适合处理需要高吞吐量的任务,因为它可以并行处理大量数据。

*局限性:MapReduce对于需要低延迟或迭代算法的任务不太合适,因为它是一个批量处理模型。

结论

MapReduce模型是一种强大的分布式计算编程模型,特别适用于处理海量数据集和高吞吐量任务。它提供可扩展性、容错性、并行性和容错性等优点,使其成为大数据处理的理想选择。第六部分CUDA模型的GPU加速并行CUDA模型的GPU加速并行

简介

CUDA(统一计算设备架构)是一种由NVIDIA开发的并行编程模型,旨在利用图形处理单元(GPU)的强大计算能力来提升并行应用程序的性能。

GPU架构

GPU采用多核架构,拥有大量并行处理内核,每个内核都可以执行独立的线程。与CPU相比,GPU具备更高的浮点性能和内存带宽,使其非常适合于并行数据密集型计算。

CUDA编程模型

CUDA模型通过提供一个抽象层,简化了在GPU上进行并行编程。它将并行代码划分为以下部分:

*内核:可并行执行的代码块,在GPU上运行。

*线程:内核中的独立执行单元,成群组组织在一个网格结构中。

*块:线程组,是GPU调度的基本单位。

数据并行性

CUDA模型利用数据并行性,将同一操作并行应用于大量数据元素。例如,如果需要计算一组数字的平方,每个线程可以处理不同的数字,从而实现并行计算。

CUDA指令

CUDA提供了一组特定的指令,用于在GPU上执行并行操作,包括:

*__global__:声明内核函数。

*__shared__:定义共享内存,由块中的所有线程访问。

*__syncthreads():同步块中的线程。

CUDA内存模型

CUDA内存模型定义了GPU上不同类型的内存,包括:

*全局内存:设备上的共享内存,可由所有线程访问。

*常量内存:只读内存,存储不变数据。

*纹理内存:优化用于存储和访问图像数据的内存。

*共享内存:块内线程之间的共享内存。

性能优化

为了优化CUDA程序的性能,可以采取以下措施:

*最大化数据并行性。

*减少内存访问冲突。

*利用共享内存。

*避免分支分歧(warps)。

CUDA应用

CUDA模型广泛应用于各种需要高性能并行计算的领域,包括:

*科学计算

*数据分析

*图像处理

*视频处理

*机器学习

优势

CUDA模型提供以下优势:

*高性能:利用GPU的并行处理能力实现卓越的性能。

*易用性:提供一个高级编程模型,简化了在GPU上的并行编程。

*广泛支持:得到NVIDIA和主要硬件供应商的广泛支持。

限制

CUDA模型也有一些限制:

*有限的内存容量:GPU内存容量有限,可能限制应用程序的大小。

*高功耗:GPU功耗较高,可能导致设备过热。

*代码移植性:CUDA代码仅在NVIDIAGPU上运行,限制了其在其他平台上的可移植性。

总结

CUDA模型是一种强大的并行编程模型,通过利用GPU的并行处理能力来大幅提升应用程序性能。其易用性和广泛的支持使其成为需要高性能并行计算的各种领域的理想选择。第七部分IntelTBB库的线程池管理关键词关键要点主题名称:IntelTBB库中线程池的调度策略

1.TBB库使用无锁队列来存储待处理任务,确保并行线程之间的轻量级交互。

2.线程池采用工作窃取算法,允许空闲线程从其他繁忙线程处窃取任务,提高资源利用率。

3.TBB库提供优先级队列,允许应用程序指定任务的优先级,从而优化任务执行顺序和资源分配。

主题名称:IntelTBB库中线程池的负载平衡

英特尔TBB库的线程池管理

英特尔线程构建模块(TBB)库是一个跨平台、轻量级且易于使用的线程库,可简化多核处理器的并行编程。TBB库提供了一系列用于管理线程池的类和函数,允许开发人员高效且可扩展地利用多核架构。

TBB线程池的主要特点:

*任务窃取调度:TBB使用任务窃取调度算法来分配任务到线程。处理器上的每个线程都会维护一个本地任务队列。如果某个线程的本地队列为空,它会从其他线程的队列中窃取任务。这种方法有助于平衡负载并在多核系统中实现高利用率。

*局部性感知:TBB线程池意识到线程局部性,并优先从本地线程队列中分配任务。这减少了线程之间的缓存争用,从而提高了性能。

*工作窃取:TBB线程池采用工作窃取策略,其中空闲线程从繁忙线程的队列中窃取工作。这有助于在多核系统中动态调整线程的负载,确保所有线程都得到有效利用。

*可扩展性:TBB线程池被设计为高度可扩展,能够高效地利用大量核心。它自动调整线程池大小以匹配系统的可用核心数,实现最优性能。

TBB线程池管理类和函数:

TBB库提供了一系列类和函数来管理线程池:

*task_scheduler_init():初始化TBB线程池,指定要创建的线程数或使用默认值。

*task_scheduler_observer():创建一个任务调度程序观察者,允许开发人员监视线程池的活动。

*task_arena():创建任务分配的域或区域。TBB线程池按域管理线程,允许对特定线程组进行细粒度控制。

*task_group():创建任务组,允许开发人员对任务进行分组并控制其执行顺序。

*parallel_for():并行执行循环,TBB线程池自动将循环迭代分配给各个线程。

*parallel_reduce():并行执行归约操作,TBB线程池自动将数据分块并分配给各个线程进行局部归约。

TBB线程池管理最佳实践:

*选择合适的线程数:线程数量应根据系统的核心数和应用程序的工作负载进行调整。一般来说,线程数量应等于或略小于核心数量。

*使用任务组:任务组可用于控制任务之间的依赖关系和执行顺序。通过将任务分组,开发人员可以优化线程利用率并提高性能。

*监视线程池活动:使用任务调度程序观察者可以监视线程池的活动,例如线程负载、任务等待时间和窃取率。这有助于识别和解决性能瓶颈。

*利用局部性感知:TBB线程池的局部性感知特性可以提高性能。尽量将相关数据分配给同一任务域或区域,以减少缓存争用。第八部分不同模型在实际场景中的适用性关键词关键要点主题名称:性能影响因素

1.数据并发性:并行模型对数据并发访问的处理方式直接影响性能。高并发性模型往往性能较好,但容易出现竞争问题。

2.算法复杂度:不同算法的并行化程度不同,影响并行模型的效率。复杂度较低的算法更容易实现并行化。

3.数据粒度:数据粒度是指并行操作中处理的数据块大小。粒度较大的模型并发度较高,但可能存在负载不均衡问题。

主题名称:编程复杂度

不同泛型并行编程模型在实际场景中的适用性

共享内存模型(OpenMP)

*适用于共享内存系统上的应用程序,其中线程共享同一地址空间。

*优点:简单易用、性能良好、广泛支持。

*适用于:数值模拟、数据处理、机器学习。

分布式内存模型(MPI)

*适用于分布式内存系统上的应用程序,其中线程运行在不同的节点上,通过消息传递进行通信。

*优点:可扩展性好、适用于大规模系统。

*适用于:高性能科学计算、集群计算、云计算。

混合并行模型

*结合共享内存和分布式内存模型,以利用不同系统的优势。

*优点:可扩展性好、性能高。

*适用于:复杂且大规模的应用程序,如气象建模、流体动力学模拟。

并行加速库模型(CUDA、OpenCL)

*利用图形处理单元(GPU)的并行计算能力,适用于数据密集型计算。

*优点:高性能、适用于并行算法。

*适用于:图像处理、视频分析、深度学习。

基于任务的模型(CilkPlus、TBB)

*基于任务的并行模型,用于细粒度并行。

*优点:简单、可扩展性好。

*适用于:服务器端应用程序、网页渲染、用户界面。

选择模型的考虑因素

*计算规模:分布式内存模型适用于大规模计算,而共享内存模型适用于中等规模计算。

*数据大小:并行加速库模型适用于数据密集型计算,而基于任务的模型适用于数据稀疏型计算。

*并行算法:不同的模型更适合不同的并行算法。共享内存模型适合共享数据结构的算法,而分布式内存模型适合分布式数据结构的算法。

*系统架构:模型的选择取决于系统的架构,例如共享内存系统或分布式内存系统。

*性能需求:高性能要求可能需要并行加速库模型或混合并行模型。

实际场景中的用例

数值模拟:OpenMP因其简单性和性能而广泛用于数值模

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论