openmp 相关问题

OpenMP是一种跨平台的多线程API,它允许使用特殊的编译器指令进行细粒度的任务并行化和同步。

与 #pragma omp for

我是并行编程的新手(刚刚在课堂上学习),我对这个指令到底做什么有点困惑......我被告知(并在线阅读)它使用工作共享得到

回答 1 投票 0

如何加速密集矩阵乘法?

我想加速倍增打击: 这是我需要改进的代码: 无效乘法(int大小,int ** matA,int ** matB,int ** matC){ for(int i=0;i 我想加速倍增打击: 这是我需要改进的代码: void multiply(int size, int **matA, int **matB, int ** matC) { for(int i=0;i<size;i++) { for(int j=0;j<size;j++) { int t = matC[i][j]; for(int k=0;k<size;k++) { t += matA[i][k] * matB[k][j]; } matC[i][j] += t; } } } 我有两个矩阵和一个大小为 5000x5000 的结果矩阵。 巨大的矩阵可能意味着它们无法完全加载到缓存中? for循环中是否出现过多页错误?我想知道如何加快乘法速度,以及如何组织数据(使用一维数组还是二维数组?) 我的答案代码是列表blow,我选择使用1d数组来模拟2d数组(每个矩阵使用new []一次),但我不确定使用2d数组时是否更快。 我使用临时矩阵来存储 matB 的转置矩阵,以避免 for 循环中的页面错误。 我添加 AVX2 以获得更高的性能。 使用大小为 5000x5000 的一维数组或二维数组哪个更好? 还有其他想法或技巧吗? int** allocate(int rows, int cols) { int ** mat; mat = new int*[rows]; int *temp = new int[rows*cols]; for(int i = 0; i<rows; i++) { mat[i] = temp + i * cols; } return mat; } void multiply(int size, int **matA, int **matB, int ** matC) { int i; int n = size*size; // total size // column-major order int **transMatB = allocate(size, size); int *transArrB = transMatB[0]; //copy transposed data, maybe many page faults here. #pragma omp parallel for for(i = 0; i < n; i++) { transMatB[i/size][i%size] = matB[i%size][i/size]; } #pragma omp parallel for for(i = 0; i < n; i ++) { int *row = matA[i / size]; int *col = transMatB[i % size]; int temp; #ifdef __AVX2__ temp = multiplyAndSumArrays(row, col, size); #else temp = 0; for (int k = 0; k < size; k ++) { temp += row[k] * col[k]; } #endif matC[i / size][i % size] += temp; } // remove temp transposed mastrix delete[] transMatB[0]; delete[] transMatB; transMatB = nullptr; } 在优化方面,矩阵-矩阵乘法可能是研究最多的内核。对于最终结果,请阅读 Goto 和 van de Geijn 的论文,引用如下。 关键在于 该算法对 n^2 数据进行 n^3 次操作,因此具有在缓存中重用数据的潜力。 简单的 3 循环版本无法重复使用,因此您需要做一些事情。 幸运的是,所有输出组件都是独立的,因此您可以对操作进行重大改组。 特别是最后一点:简而言之,3 个循环中的每一个都分为两个循环,一个在块上,一个在块内。然后你有 6 个循环(意味着 5 个!左右不同的算法)和 3 个块大小作为调整参数。上面的论文对此分析得很完整。 请注意,这并不简单!对于合理可行的解决方案,请执行递归 2x2 乘法:将每个矩阵划分为 2x2 块结构,然后递归地相乘。当块足够小以适合缓存时,您将停止递归。 这应该可以作为课堂作业来实现,从而提高成绩。您甚至可以简单地进行多线程处理。 Goto, Kazushige / Geijn, Robert A. van de Anatomy of high-performance matrix multiplication 2008 ACM Trans. Math. Softw. , Vol. 34, No. 3 ACM: New York, NY, USA p. 1-25

回答 1 投票 0

如何在C++中使用Openmp加速矩阵乘法?

我想加速倍增打击: 这是我需要改进的代码: 无效乘法(int大小,int ** matA,int ** matB,int ** matC){ for(int i=0;i 我想加速倍增打击: 这是我需要改进的代码: void multiply(int size, int **matA, int **matB, int ** matC) { for(int i=0;i<size;i++) { for(int j=0;j<size;j++) { int t = matC[i][j]; for(int k=0;k<size;k++) { t += matA[i][k] * matB[k][j]; } matC[i][j] += t; } } } 我有两个矩阵和一个大小为 5000x5000 的结果矩阵。 巨大的矩阵可能意味着它们无法完全加载到缓存中? for循环中是否出现过多页错误?我想知道如何加速乘法,以及如何组织数据(使用一维数组还是二维数组?) 我的答案代码是列表blow,我选择使用1d数组来模拟2d数组(每个矩阵使用new []一次),但我不确定使用2d数组时是否更快。 我使用临时矩阵来存储 matB 的转置矩阵,以避免 for 循环中的页面错误。 我添加 AVX2 以获得更高的性能。 使用大小为 5000x5000 的一维数组或二维数组哪个更好? 还有其他想法或技巧吗? int** allocate(int rows, int cols) { int ** mat; mat = new int*[rows]; int *temp = new int[rows*cols]; for(int i = 0; i<rows; i++) { mat[i] = temp + i * cols; } return mat; } void multiply(int size, int **matA, int **matB, int ** matC) { int i; int n = size*size; // total size // column-major order int **transMatB = allocate(size, size); int *transArrB = transMatB[0]; //copy transposed data, maybe many page faults here. #pragma omp parallel for for(i = 0; i < n; i++) { transMatB[i/size][i%size] = matB[i%size][i/size]; } #pragma omp parallel for for(i = 0; i < n; i ++) { int *row = matA[i / size]; int *col = transMatB[i % size]; int temp; #ifdef __AVX2__ temp = multiplyAndSumArrays(row, col, size); #else temp = 0; for (int k = 0; k < size; k ++) { temp += row[k] * col[k]; } #endif matC[i / size][i % size] += temp; } // remove temp transposed mastrix delete[] transMatB[0]; delete[] transMatB; transMatB = nullptr; } 提供的矩阵乘法代码可以通过多种方式进行优化,以提高其性能,特别是对于 5000x5000 这样的大型矩阵。以下是优化及其影响的详细信息: 缓存阻塞: 矩阵乘法的简单实现,如所提供的代码所示,由于数据局部性较差而导致缓存未命中。缓存分块涉及将矩阵划分为适合 CPU 缓存的较小块,从而减少缓存未命中次数并提高性能。 数据布局: 对矩阵使用列优先顺序可以提高缓存性能,因为它减少了遍历列所需的内存访问次数。这是因为列中的连续元素存储在连续的内存位置中。 转置内矩阵: 转置内部矩阵(本例中为 matB)可以进一步提高缓存利用率,特别是对于大型矩阵。当内部矩阵转置时,它的列变成它的行,从而为内部循环带来更好的缓存局部性。 使用 AVX2 说明: 采用AVX2(高级矢量扩展2)指令可以显着加速内循环内的乘法和求和运算。 AVX2 指令可以同时对多个数据元素执行多个操作,从而增强矢量化操作的性能。 避免页面错误: 在使用转置矩阵 (matB) 之前将其复制到临时数组中可以帮助减少页面错误,尤其是对于大型矩阵。这可确保在访问整个转置矩阵之前将其加载到内存中,从而最大限度地减少计算期间的页面错误数量。 使用一维或二维数组: 一维和二维阵列都有各自的优点和缺点。一维数组的内存效率更高,但它们需要额外的索引计算来访问元素。二维数组提供对元素的直接访问,但可能具有更高的内存开销。一维和二维数组之间的选择取决于具体的使用情况和内存限制。 并行度: 利用并行处理技术(例如 OpenMP)可以通过将计算分布到多个内核或线程来进一步提高性能。这可以显着减少整体执行时间,尤其是对于大型矩阵。 通过合并这些优化,矩阵乘法代码可以实现显着的性能改进,特别是对于 5000x5000 等大型矩阵。

回答 1 投票 0

为什么我无法在合并排序程序中使用 OpenMP 任务?

我已经实现了并行合并排序,但是当我去编译它时,我收到此错误:'task':需要'-openmp:llvm'命令行选项 我尝试在命令行选项中添加标志(

回答 2 投票 0

OpenMP:Fortran:在矩阵上添加约简

我有一个名为 DATA 的大型 N×T 元素矩阵(T 是线程数)。我想添加每行 DATA 的元素以生成名为 SUM 的单个 N 元素输出向量。这是连续剧

回答 1 投票 0

通过 OpenMP 提高速度并减少速度

我会使用 OpenMP 提高这些代码的速度。 对于 (i = 1; i < length; i++) { for (j = 1; j < i; j++) sum_c += c[j]; c[i] = sum_c + W[i]; sum_c = 0; } I try with these sol...

回答 1 投票 0

长时间运行时程序停止

我正在运行 Ubuntu 服务器 10.04.3 的计算机上运行模拟。短期运行(<24 hours) run fine, but long runs eventually stall. By stall, I mean that the program no longer gets any CPU t...

回答 3 投票 0

Cuda 多设备异步与可分页内存

Cuda 是否提供了一种使用主机上的可分页内存在不同设备之间获得异步性的方法? (请注意,这并不是关于阻止 cudaMemcpyAsync 的无休止的问题

回答 1 投票 0

多线程仅打印一次字符串

我想编写一个简单的代码,使用 4 个线程打印“Hello world”4 次: #包括 #包括 #include“omp.h” int 主函数(无效){ #p...

回答 1 投票 0

使用多线程时加速低于预期

备注:我觉得这有点愚蠢,但这可能对某人有帮助 因此,我试图通过使用并行性来提高程序的性能。但是,我遇到了问题

回答 1 投票 0

使用Qt Creator时如何打开OpenMP

如果我使用 VS 2010 编译器从 Qt 创建者构建项目,我如何启用 OpenMP(从 Visual Studio 构建时,只需启用该功能)谢谢

回答 2 投票 0

如何使用本地版本的openMP? (GOMP)

我想对我从 (git repo) 下载的 GOMP 库进行一些更改(只是暂时打印一些内容)[https://github.com/gcc-mirror/gcc.git% 5C] 但看起来就像我正在做的...

回答 1 投票 0

在并行循环的子例程中通过传递的索引处理共享数组

在并行循环中,我使用子例程处理共享数组,将数组和当前私有索引作为参数传递给该子例程,但程序因数组越界错误而崩溃。 ...

回答 1 投票 0

向量化一个带有“继续”分支的循环

我目前正在学习一门课程,在该课程中我们可以使用超级计算机。 CPU 是 Intel(R) Xeon(R) Gold 6240 CPU。我们的任务是矢量化(但我们不被允许使用

回答 1 投票 0

Jupyter 内核在训练 LightFM 模型“fit_partial”时死机

最初从 lightfm.datasets import fetch_movielens 导入时,我得到以下输出: 用户警告:LightFM 是在没有 OpenMP 支持的情况下编译的。仅使用单个线程。 然后,我

回答 1 投票 0

当 clang 构建的程序同时链接 libomp 和 libgomp 时会发生什么?

我有一个 C/C++ 程序,其中包含来自我的 Linux 发行版的各种依赖项。 一些依赖项与 GCC 的 OpenMP 库 libgomp.so 链接。 我的程序本身有它的代码编译...

回答 1 投票 0

OpenMP 对 `_CRT_fenv' 和 `_setargv' 的未定义引用

我正在尝试运行这个简单的 OpenMP 示例: #包括 #包括 使用命名空间 std; int main() { 开关(_OPENMP){ 案例200805: 计算<< "Op...

回答 2 投票 0

clang OpenMP 循环继续计数超出循环条件限制

我有以下有趣的问题: #包括 #包括 使用命名空间 std; int main(const int, const char **) { 常量 size_t n = 13; // 触发问题 ...

回答 1 投票 0

tensorflow_cc 导致对 `omp_in_parallel@VERSION' 的未定义引用

我在 Arch linux 上安装了tensorflow-opt-cuda,但尝试链接为 g++ -fopenmp "CMakeFiles/intro-hello-world.dir/hello-world.cc.o" -o intro-hello-world /usr/lib/libtensorflow_cc.so /us...

回答 1 投票 0

为什么缩减不能用于 OpenMP 任务?

这是计算曼德尔布罗特集面积的数值近似值的代码。我不明白为什么在声明时我不能写duction(+ : numoutside)而不是shared(numoutside)...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.