为什么我在c中的Matrix Multipication代码总是给出垃圾值?(使用共享内存和派生)

索拉维奇

这是我在c中执行矩阵乘法实现fork和共享内存的代码。看来我得到的价值主要是垃圾价值。也许我没有初始化数组C的值,它首先是结果数组。(我是C的初学者,这是我第一次使用共享内存)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define N 3

void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[]);
int main()
{
    int Ma[N][N];
    int Mb[N][N];
    int segment_id;
    pid_t pid=-1;

        printf("Input the elements in Matrix A (%dx%d) : \n",N,N);
        for(int k = 0; k<N ;k++)
        {
                for(int d = 0; d<N ; d++)
                {
                        scanf("%d",&Ma[k][d]);
                }
        }
        printf("Input the elements in Matrix B (%dx%d) : \n",N,N);
        for(int k = 0; k<N ;k++)
        {
                for(int d = 0; d<N ; d++)
                {
                        scanf("%d",&Mb[k][d]);
                }
        }

    segment_id = shmget(IPC_PRIVATE,1024, S_IRUSR|S_IWUSR);
        int *C = (int*)shmat(segment_id,NULL,0);

    for(int i=0;i<N*N;i++)
    {
        if(pid != 0)
        {
            pid = fork();
        }
    }

    if(pid == 0)
    {
        for(int i = 0; i<N; i++)
        {
            for(int j =0; i<N; j++)
            {
                if(C[i*N+j]==0)
                {
                    doMulT(i,j,N,Ma,Mb,C);
                }
            }
        }
    }

    else
    {
        for(int k =0;k<N*N;k++)
        {
            wait(NULL);
        }
        printf("==========Result==========\n");
            for(int i=0; i<N; i++)
            {
                    for(int j=0; j<N; j++)
                    {
                            printf("%d",C[i*N+j]);
                            printf(" ");
                    }
                    printf("\n");
            }
        }
    shmdt(C);
        shmctl(segment_id, IPC_RMID, NULL);
}

void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[])
{
        for(int k=0; k<x; k++)
        {
             c[row*x+col]+=a[row][k]*b[k][col];
        }
}

输入的例子

Input the elements in Matrix A (3x3) :
1 1 1
2 2 2
3 3 3
Input the elements in Matrix B (3x3) :
1 1 1
2 2 2
3 3 3

输出就像

6 6 6
123482868 -745374 -2637821
456729394 -98475839 -2884829
博多

该答案的第一部分旨在显示原始程序中的问题以及调试问题的方法。

我添加了一些printf输出以查看流程将执行的操作

    if(pid == 0)
    {
        for(int i = 0; i<N; i++)
        {
            for(int j =0; i<N; j++)
            {
                if(C[i*N+j]==0)
                {
                    printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
                    doMulT(i,j,N,Ma,Mb,C);
                }
            }
        }
    }

并得到这样的输出:

process 747 calculating (0, 204)                                                                                                                                                               
process 746 calculating (0, 292)                                                                                                                                                               
process 746 calculating (0, 293)                                                                                                                                                               
process 747 calculating (0, 205)                                                                                                                                                               
process 746 calculating (0, 294)                                                                                                                                                               
process 747 calculating (0, 206)                                                                                                                                                               
process 746 calculating (0, 295)                                                                                                                                                               
process 747 calculating (0, 207)                                                                                                                                                               

这意味着for的循环j是错误的。

有一个错字:

            for(int j =0; i<N; j++)

必须是

            for(int j =0; j<N; j++) // j<N  instead of  i<N

另外,我曾经memset用0初始化共享内存。

修复循环后,我得到

process 238 calculating (0, 0)                                                                                                                                                              
process 238 calculating (0, 1)                                                                                                                                                              
process 238 calculating (0, 2)                                                                                                                                                              
process 238 calculating (1, 0)                                                                                                                                                              
process 238 calculating (1, 1)                                                                                                                                                              
process 238 calculating (1, 2)                                                                                                                                                              
process 238 calculating (2, 0)                                                                                                                                                              
process 238 calculating (2, 1)                                                                                                                                                              
process 238 calculating (2, 2)                                                                                                                                                              
==========Result==========                                                                                                                                                                  
6 6 6                                                                                                                                                                                       
12 12 12                                                                                                                                                                                    
18 18 18                                                                                                                                                                                    

这意味着一个孩子在其他孩子变得活跃之前就完成了所有工作。

处理循环中的延迟为其他进程提供了一些工作的机会。

注意:这并不是真正的解决方案。主要目的是表明您不能依赖系统在流程之间分配工作。

它还显示矩阵乘法不是用于多处理的好用例,因为矩阵单元的计算(至少对于您的示例中的小矩阵而言)显然比创建新过程快得多。

    if(pid == 0)
    {
        for(int i = 0; i<N; i++)
        {
            for(int j =0; j<N; j++)
            {
                if(C[i*N+j]==0)
                {
                    printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
                    doMulT(i,j,N,Ma,Mb,C);
                    sleep(1); // give other processes a chance to do some work
                }
            }
        }
    }

为了获得良好的解决方案,您必须实现一种为每个子进程分配特定任务的方法。一种选择是将循环变量i(或对于行和列可能使用两个单独的循环变量)传递给子进程中的处理函数,如以下版本所示。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <memory.h>
#include <errno.h>
#include <stdlib.h>

#define N 3
#define SIZE 1024

void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[]);
int main()
{
    int Ma[N][N] = {
        {1, 1, 1},
        {2, 2, 2},
        {3, 3, 3}
    };
    int Mb[N][N] = {
        {1, 1, 1},
        {2, 2, 2},
        {3, 3, 3}
    };
    int segment_id;
    pid_t pid=-1;

#if 0
        printf("Input the elements in Matrix A (%dx%d) : \n",N,N);
        for(int k = 0; k<N ;k++)
        {
                for(int d = 0; d<N ; d++)
                {
                        scanf("%d",&Ma[k][d]);
                }
        }
        printf("Input the elements in Matrix B (%dx%d) : \n",N,N);
        for(int k = 0; k<N ;k++)
        {
                for(int d = 0; d<N ; d++)
                {
                        scanf("%d",&Mb[k][d]);
                }
        }
#endif

    segment_id = shmget(IPC_PRIVATE, SIZE, S_IRUSR|S_IWUSR);
        int *C = (int*)shmat(segment_id,NULL,0);

    memset(C, 0, SIZE);
    
    for(int i=0; (pid != 0) && (i<N); i++)
    {
        for(int j=0; (pid != 0) && (j<N); j++)
        {
            if(pid != 0)
            {
                pid = fork();
                if(pid == 0)
                {
                    printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
                    doMulT(i,j,N,Ma,Mb,C);
                    exit(0);
                }
            }
        }
    }


    if(pid != 0)
    {
        while(wait(NULL) != -1 || (errno != ECHILD))
        {
            ;
        }
        printf("==========Result==========\n");
            for(int i=0; i<N; i++)
            {
                    for(int j=0; j<N; j++)
                    {
                            printf("%d",C[i*N+j]);
                            printf(" ");
                    }
                    printf("\n");
            }
        }
    shmdt(C);
        shmctl(segment_id, IPC_RMID, NULL);
}

void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[])
{
        for(int k=0; k<x; k++)
        {
             c[row*x+col]+=a[row][k]*b[k][col];
        }
}

输出如下:

process 7489 calculating (0, 0)                                                                                                                                                             
process 7495 calculating (2, 0)                                                                                                                                                             
process 7496 calculating (2, 1)                                                                                                                                                             
process 7497 calculating (2, 2)                                                                                                                                                             
process 7493 calculating (1, 1)                                                                                                                                                             
process 7490 calculating (0, 1)                                                                                                                                                             
process 7494 calculating (1, 2)                                                                                                                                                             
process 7492 calculating (1, 0)                                                                                                                                                             
process 7491 calculating (0, 2)                                                                                                                                                             
==========Result==========                                                                                                                                                                  
6 6 6                                                                                                                                                                                       
12 12 12                                                                                                                                                                                    
18 18 18                                                                                                                                                                                    

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的数组值不在共享内存中交换?

来自分类Dev

为什么这样工作?我不明白为什么我的代码可以在C中工作

来自分类Dev

为什么断点会在我的C ++代码中跳转?

来自分类Dev

为什么断点会在我的C ++代码中跳转?

来自分类Dev

为什么我的if语句在React中总是给出相同的结果?

来自分类Dev

为什么我的C ++代码在ideone和Codeforces自定义测试中给出2个不同的输出?

来自分类Dev

为什么我从函数调用中获取垃圾值?

来自分类Dev

为什么我在EOutOfResources中泄漏内存?

来自分类Dev

为什么我的C中的sin计算代码返回错误的值?

来自分类Dev

为什么 C# 代码总是让 Unity 崩溃?(我是 Unity 和 C# 的初学者)

来自分类Dev

为什么我的随机列表中的值总是相同?

来自分类Dev

为什么在我的代码中需要 ',' 或 ')'?

来自分类Dev

为什么我的代码中的 if 语句被忽略?

来自分类Dev

为什么我们必须在Java脚本(Razor)中对C#代码使用引号

来自分类Dev

为什么我不能使用cout在C ++中打印字符串值的数组?

来自分类Dev

为什么我的bool属性没有使用C#中的Get / Set接收值?

来自分类Dev

为什么我在动态内存中得到错误的值?

来自分类Dev

为什么在我的C代码中不能将“ long long int”和“ int”一起使用?

来自分类Dev

为什么我的C ++并行程序在MPI_Gather中给出MPI致命错误?

来自分类Dev

为什么我的C ++并行程序在MPI_Gather中给出MPI致命错误?

来自分类Dev

为什么我的 for 循环没有在 C 中给出预期的输出?

来自分类Dev

为什么我的代码仅通过注释c ++中的单个打印cout语句来给出不同的输出?

来自分类Dev

为什么模数操作数对我的C代码中的输入变量不起作用?

来自分类Dev

为什么Oracle 12c的数据字典中缺少我的plsql代码?

来自分类Dev

C ++为什么我的代码将注册表项放在错误的目录中?

来自分类Dev

为什么我的代码在C ++中不反转字符串?

来自分类Dev

为什么我的C ++程序的汇编输出中充满了.ascii而没有汇编代码?

来自分类Dev

c#:为什么GC无法在我的代码中收集Weakreference的目标?

来自分类Dev

C ++为什么我的代码将注册表项放在错误的目录中?

Related 相关文章

  1. 1

    为什么我的数组值不在共享内存中交换?

  2. 2

    为什么这样工作?我不明白为什么我的代码可以在C中工作

  3. 3

    为什么断点会在我的C ++代码中跳转?

  4. 4

    为什么断点会在我的C ++代码中跳转?

  5. 5

    为什么我的if语句在React中总是给出相同的结果?

  6. 6

    为什么我的C ++代码在ideone和Codeforces自定义测试中给出2个不同的输出?

  7. 7

    为什么我从函数调用中获取垃圾值?

  8. 8

    为什么我在EOutOfResources中泄漏内存?

  9. 9

    为什么我的C中的sin计算代码返回错误的值?

  10. 10

    为什么 C# 代码总是让 Unity 崩溃?(我是 Unity 和 C# 的初学者)

  11. 11

    为什么我的随机列表中的值总是相同?

  12. 12

    为什么在我的代码中需要 ',' 或 ')'?

  13. 13

    为什么我的代码中的 if 语句被忽略?

  14. 14

    为什么我们必须在Java脚本(Razor)中对C#代码使用引号

  15. 15

    为什么我不能使用cout在C ++中打印字符串值的数组?

  16. 16

    为什么我的bool属性没有使用C#中的Get / Set接收值?

  17. 17

    为什么我在动态内存中得到错误的值?

  18. 18

    为什么在我的C代码中不能将“ long long int”和“ int”一起使用?

  19. 19

    为什么我的C ++并行程序在MPI_Gather中给出MPI致命错误?

  20. 20

    为什么我的C ++并行程序在MPI_Gather中给出MPI致命错误?

  21. 21

    为什么我的 for 循环没有在 C 中给出预期的输出?

  22. 22

    为什么我的代码仅通过注释c ++中的单个打印cout语句来给出不同的输出?

  23. 23

    为什么模数操作数对我的C代码中的输入变量不起作用?

  24. 24

    为什么Oracle 12c的数据字典中缺少我的plsql代码?

  25. 25

    C ++为什么我的代码将注册表项放在错误的目录中?

  26. 26

    为什么我的代码在C ++中不反转字符串?

  27. 27

    为什么我的C ++程序的汇编输出中充满了.ascii而没有汇编代码?

  28. 28

    c#:为什么GC无法在我的代码中收集Weakreference的目标?

  29. 29

    C ++为什么我的代码将注册表项放在错误的目录中?

热门标签

归档