Tag: hpc

MPI中的进程数量是否有限制?

我正在阅读“使用MPI”并尝试自己执行代码。 第6.3章中有一个网格分解代码。 它编译时没有任何警告或错误,并且使用少量进程运行,但在我的笔记本电脑上失败,但数量更大,比如30。 我的笔记本电脑是4核,超线程和8G内存。 la_grid_2d_new两个版本都不起作用,但第一个版本可以容忍更大的数字,比如35,但是40个进程失败了。 我不知道为什么。 请问你能帮帮我吗? 非常感谢。 #include #include #include typedef struct { int P, Q; int p, q; MPI_Comm grid_comm; MPI_Comm row_comm; MPI_Comm col_comm; } LA_Grid_2d; LA_Grid_2d *la_grid_2d_new(MPI_Comm comm, int P, int Q) { LA_Grid_2d *grid; MPI_Comm row, col; int my_rank, p, q; MPI_Comm_rank(comm, &my_rank); p=my_rank/Q; q=my_rank%Q; MPI_Comm_split(comm, p, q, &row); MPI_Comm_split(comm, q, […]

为什么这个MPI代码执行不正常?

我正在努力创造一个“Hello,world!” 在(开放)MPI中应用,使每个过程按顺序打印出来。 我的想法是让第一个进程在完成时向第二个进程发送消息,然后在第二个到第三个进程发送消息,等等: #include #include int main(int argc,char **argv) { int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); // See: http://mpitutorial.com/mpi-send-and-receive/ if (rank == 0) { // This is the first process. // Print out immediately. printf(“Hello, World! I am rank %d of %d.\n”, rank, size); MPI_Send(&rank, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); } else […]

如何在Opensuse 12.2上构建Gotoblas2

使用默认的make文件在我的x86_64上构建GotoBlas2时,遇到以下构建错误: gcc -O2 -DEXPRECISION -m128bit-long-double -Wall -m64 -DF_INTERFACE_GFORT -fPIC -DSMP_SERVER -DMAX_CPU_NUMBER = 8 -DASMNAME = -DASMFNAME = _ -DNAME = _ -DCNAME = -DCHAR_NAME = \“_ \” – DCHAR_CNAME = \“\”-I .. -w -o linktest linktest.c ../libgoto2_nehalemp-r1.13.so -L / usr / lib64 / gcc / x86_64-suse-linux / 4.7 -L / usr / lib64 / gcc […]

MPI_Isend和MPI_Irecv似乎导致死锁

我在MPI中使用非阻塞通信在进程之间发送各种消息。 但是,我似乎陷入了僵局。 我使用PADB( 请参阅此处 )查看消息队列并获得以下输出: 1:msg12: Operation 1 (pending_receive) status 0 (pending) 1:msg12: Rank local 4 global 4 1:msg12: Size desired 4 1:msg12: tag_wild 0 1:msg12: Tag desired 16 1:msg12: system_buffer 0 1:msg12: Buffer 0xcaad32c 1:msg12: ‘Receive: 0xcac3c80’ 1:msg12: ‘Data: 4 * MPI_FLOAT’ — 1:msg32: Operation 0 (pending_send) status 2 (complete) 1:msg32: Rank local 4 […]

使用MPI_Type_create_subarray发送时可以转置数组吗?

我试图在C中使用MPI转置矩阵。每个进程都有一个方形子矩阵,我想将它发送到正确的进程(网格上的“对面”),将其转换为通信的一部分。 我正在使用MPI_Type_create_subarray ,它有一个订单参数,分别是行主要和列主要的MPI_ORDER_C或MPI_ORDER_FORTRAN 。 我认为,如果我作为其中一个发送,并作为另一个接收,那么我的矩阵将被转换为通信的一部分。 然而,这似乎并没有发生 – 它只是保持非转置。 代码的重要部分如下所示,整个代码文件都可以在这个要点中找到 。 有没有人有任何想法为什么这不起作用? 这种方法是否应该进行转置工作? 我已经想过,在阅读了MPI_ORDER_C和MPI_ORDER_FORTRAN的描述MPI_ORDER_FORTRAN ,但也许没有。 /* ———– DO TRANSPOSE ———– */ /* Find the opposite co-ordinates (as we know it’s a square) */ coords2[0] = coords[1]; coords2[1] = coords[0]; /* Get the rank for this process */ MPI_Cart_rank(cart_comm, coords2, &rank2); /* Send to these new coordinates […]

如何使用Dot产品获得峰值CPU性能?

问题 我一直在研究HPC,特别是使用矩阵乘法作为我的项目(参见我在配置文件中的其他post)。 我在那些方面取得了不错的成绩,但还不够好。 我退后一步看看我能用点积计算做得多好。 点乘积与矩阵乘法 点积更简单,我可以在不处理打包和其他相关问题的情况下测试HPC概念。 缓存阻塞仍然是一个问题,这是我的第二个问题。 算法 将两个double数组A和B n相应元素相乘并求它们。 assembly中的double点产品只是一系列movapd , mulpd , addpd 。 以巧妙的方式展开和排列,可以使movapd / mulpd / addpd组在不同的xmm寄存器上运行,因此是独立的,优化了流水线操作。 当然,事实certificate,这与我的CPU无序执行无关。 还要注意,重新安排需要剥离最后一次迭代。 其他假设 我不是在编写通用点积的代码。 代码是针对特定尺寸的,我不处理边缘情况。 这只是为了测试HPC概念并查看我可以获得的CPU使用类型。 结果 编译为gcc -std=c99 -O2 -m32 -mincoming-stack-boundary=2 -msse3 -mfpmath=sse,387 -masm=intel 。 我和平时不同的电脑。 这台计算机有一个i5 540m ,在两步Intel Turbo Boost之后, 2.8 GHz * 4 FLOPS/cycle/core = 11.2 GFLOPS/s per core可以获得2.8 GHz * […]

如何让GCC完全展开这个循环(即剥离这个循环)?

有没有办法指示GCC(版本我使用4.8.4)完全展开底部函数中的while循环,即剥离此循环? 循环的迭代次数在编译时是已知的:58。 我先解释一下我的尝试。 通过检查GAS输出: gcc -fpic -O2 -S GEPDOT.c 使用12个寄存器XMM0 – XMM11。 如果我将标志-funroll-loops传递给gcc: gcc -fpic -O2 -funroll-loops -S GEPDOT.c 循环只展开两次。 我检查了GCC优化选项。 GCC表示-funroll-loops也会打开-frename-registers ,所以当GCC展开一个循环时,它先前选择的寄存器分配是使用“遗留”寄存器。 但是XMM12只剩下4个 – XMM15,所以GCC最多只能展开2次。 如果有48个而不是16个XMM寄存器可用,GCC将毫无困难地展开while循环4次。 然而我做了另一个实验。 我首先手动两次展开while循环,获得一个函数GEPDOT_2。 然后两者之间没有任何区别 gcc -fpic -O2 -S GEPDOT_2.c 和 gcc -fpic -O2 -funroll-loops -S GEPDOT_2.c 由于GEPDOT_2已用完所有寄存器,因此不执行展开。 GCC确实注册了重命名,以避免引入潜在的错误依赖。 但我确信在我的GEPDOT中没有这样的潜力; 即使有,也不重要。 我尝试自己展开循环,展开4次比展开2次更快,比没有展开更快。 当然我可以手动展开更多次,但这很乏味。 GCC可以帮我吗? 谢谢。 // C file “GEPDOT.c” #include […]

openmp – 用于文本文件读取和使用管道的while循环

我发现openmp不支持while循环(或者至少不太喜欢它们)。 而且也不喜欢’!=’运算符。 我有这段代码。 int count = 1; #pragma omp parallel for while ( fgets(buff, BUFF_SIZE, f) != NULL ) { len = strlen(buff); int sequence_counter = segment_read(buff,len,count); if (sequence_counter == 1) { count_of_reads++; printf(“\n Total No. of reads: %d \n”,count_of_reads); } count++; } 关于如何管理这个的任何线索? 我在某地读过(包括stackoverflow的另一篇文章)我可以使用管道。 那是什么 ? 以及如何实施它?

GCC SSE代码优化

这篇文章与我几天前发布的另一篇文章密切相关。 这一次,我编写了一个简单的代码,它只添加了一对元素数组,将结果乘以另一个数组中的值并将其存储在第四个数组中,所有变量浮点数都是双精度类型。 我制作了两个版本的代码:一个是SSE指令,使用调用而另一个没有它我然后用gcc和-O0优化级别编译它们。 我在下面写下: // SSE VERSION #define N 10000 #define NTIMES 100000 #include #include #include #include double a[N] __attribute__((aligned(16))); double b[N] __attribute__((aligned(16))); double c[N] __attribute__((aligned(16))); double r[N] __attribute__((aligned(16))); int main(void){ int i, times; for( times = 0; times < NTIMES; times++ ){ for( i = 0; i <N; i+= 2){ __m128d mm_a = _mm_load_pd( […]