首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我在c中的矩阵乘法代码总是给出无用的值?(使用共享内存和fork)

在C语言中使用共享内存和fork进行矩阵乘法时,可能会遇到一些问题,导致结果不正确或输出无用的值。以下是一些可能的原因和解决方法:

基础概念

  1. 共享内存:多个进程可以访问同一块物理内存区域,从而实现进程间的数据共享。
  2. fork:创建一个新进程,新进程是原进程的副本,拥有相同的内存空间和资源。

可能的原因

  1. 竞态条件:多个进程同时读写同一块内存,导致数据不一致。
  2. 同步问题:进程间没有正确同步,导致计算顺序错误。
  3. 内存分配问题:共享内存的分配和使用不当,导致数据覆盖或丢失。
  4. 初始化问题:共享内存区域未正确初始化,导致计算结果错误。

解决方法

  1. 使用互斥锁:确保同一时间只有一个进程可以访问共享内存。
  2. 同步机制:使用信号量或其他同步机制来控制进程的执行顺序。
  3. 正确初始化:确保共享内存区域在使用前被正确初始化。
  4. 检查内存分配:确保共享内存的分配和使用是正确的。

示例代码

以下是一个简单的示例,展示如何使用共享内存和fork进行矩阵乘法,并使用互斥锁来避免竞态条件:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>

#define ROWS 3
#define COLS 3

int shmid;
int *matrixA, *matrixB, *result;
pthread_mutex_t mutex;

void multiply(int start, int end) {
    for (int i = start; i < end; i++) {
        for (int j = 0; j < COLS; j++) {
            result[i * COLS + j] = 0;
            for (int k = 0; k < COLS; k++) {
                result[i * COLS + j] += matrixA[i * COLS + k] * matrixB[k * COLS + j];
            }
        }
    }
}

int main() {
    // 创建共享内存
    shmid = shmget(IPC_PRIVATE, ROWS * COLS * 3 * sizeof(int), IPC_CREAT | 0666);
    if (shmid < 0) {
        perror("shmget");
        exit(1);
    }

    // 映射共享内存
    matrixA = (int *)shmat(shmid, NULL, 0);
    matrixB = matrixA + ROWS * COLS;
    result = matrixB + ROWS * COLS;

    // 初始化矩阵
    for (int i = 0; i < ROWS * COLS; i++) {
        matrixA[i] = i + 1;
        matrixB[i] = i + 1;
    }

    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    // 创建子进程
    pid_t pid = fork();
    if (pid == 0) {
        // 子进程计算
        multiply(0, ROWS / 2);
        exit(0);
    } else if (pid > 0) {
        // 父进程计算
        multiply(ROWS / 2, ROWS);
        wait(NULL);
    } else {
        perror("fork");
        exit(1);
    }

    // 打印结果
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", result[i * COLS + j]);
        }
        printf("\n");
    }

    // 分离共享内存
    shmdt(matrixA);

    // 删除共享内存
    shmctl(shmid, IPC_RMID, NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

参考链接

通过以上方法和示例代码,你应该能够解决矩阵乘法代码中出现无用值的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

RTX 40时代,给深度学习买显卡居然能保值9年?仔细一算绷不住了

这里展示一个简单 A×B=C 矩阵乘法示例,其中所有矩阵大小均为 32×32,计算模式使用使用 Tensor Cores 时样子。...128 kb):~34 个周期 融合乘法和加法,ab+c (FFMA):4 个周期张量核心矩阵乘法:1 个周期 每个操作总是由一组 32 个线程执行,它集合被称为线程 warp。...没有张量核矩阵乘法 如果我们想要进行 A×B=C 矩阵乘法,其中每个矩阵大小为 32×32,那么就要将重复访问内存加载到共享内存,因为它延迟大约低五倍(200 周期对 34 周期)。...要进行矩阵乘法,我们现在要从共享内存 A 共享内存 B 加载一个包含 32 个数字向量,并执行融合乘加 (FFMA)。然后将输出存储寄存器 C 。...我们划分工作,使每个 SM 进行 8 次点积 (32×32) 来计算 C 8 个输出。为什么这恰好是 8(旧算法为 4)是非常技术性

1.3K40

硬件高效线性注意力机制Gated Linear Attention论文阅读

不过 https://github.com/sustcsonglin/flash-linear-attention 官方仓库以及Paper给出GLA算法伪代码中都看到只有一次分块,不太清楚原因。...内存层次结构 GPU具有内存层次结构,包括较大但速度较慢全局GPU内存(高带宽内存,HBM)较小但速度较快共享内存(SRAM)。...算法有一个materialize参数来控制是否要重计算S,然后计算过程无论是否要重计算S都会遵循分块加载Q,K,V到共享内存,然后我们就可以重用共享内存块状Tensor来避免多次加载HBM I...然而,与普通线性注意力不同,公式4不能通过标准矩阵乘法表示,并且无法张量核心上使用半精度矩阵乘法。...paper附录C图7提供了PyTorch风格代码内存高效 计算 过去工作声称GLA类模型必须将大小为 矩阵隐藏状态存储HBM,以计算所有梯度 ,因为 。

26210
  • OpenBLAS项目与矩阵乘法优化 | 公开课+文字转录

    刚才主要介绍了OpenBLAS性能效果,我们GitHub上做了托管,欢迎对矩阵乘法或优化感兴趣同学能加入进来,贡献代码,我们公司愿意拿出一笔钱来支持这个项目继续往前走。...把他内容基本上是抠出来了,一步步带着大家过一下,如果我们从最简单矩阵乘法实现,到一个高性能矩阵乘法实现,大概是几步,怎么来?或者是为什么优化,每一步能获得多少性能收益。...想只要学过《线性代数》之类,这种矩阵乘法,是一个非常简单问题,如果转换成C代码来做的话,就是一个三重循环,在这张图里列出了一个【i j k】三重循环,这里面矩阵乘法代码就已经是,它实现功能就是矩阵...当我们分析程序存在性能瓶颈,对于A访存B访存是比较慢,很多访存在矩阵是不连续,所以访存性能就差了很多,一方面不能利用cache,一方面TLB上也有影响,当然C部分也有一些影响,C矩阵往往很大...,没有办法做packing,只能对AB来做,packing意思是说,在这里有一部分连续内存空间,m*k,对应前面的mckc,在这块内存空间,每次做计算之前,把所需要用到A矩阵,从原始矩阵读取出来

    4.4K71

    先了解下这个问题第一性原理

    另一方面,如果你正在运行大量矩阵乘法运算(也就是计算紧张时候),将你程序重写成 C++ 去减轻额外开销就不会管用。...但是,为了让你钱从你昂贵矩阵乘法得到回报,你需要减少花费在其他部分时间。 但为什么这里重点是最大化计算,而不是最大化内存带宽?...事实上,归一化运算逐点(pointwise)运算使用 FLOPS 仅为矩阵乘法 1/250 1/700。那为什么矩阵乘法运算会远比它们应该使用运行时间更多呢?...,就可以计算每个 repeat FLOPS 内存带宽。...尽管 PyTorch 是一个活跃关注领域,但 PyTorch 编译器或配置文件 API 并不是最容易使用。 总而言之,发现对系统基本原理理解几乎总是有用,希望这对你也有用。

    75010

    先了解下这个问题第一性原理

    另一方面,如果你正在运行大量矩阵乘法运算(也就是计算紧张时候),将你程序重写成 C++ 去减轻额外开销就不会管用。...但是,为了让你钱从你昂贵矩阵乘法得到回报,你需要减少花费在其他部分时间。 但为什么这里重点是最大化计算,而不是最大化内存带宽?...事实上,归一化运算逐点(pointwise)运算使用 FLOPS 仅为矩阵乘法 1/250 1/700。那为什么矩阵乘法运算会远比它们应该使用运行时间更多呢?...,就可以计算每个 repeat FLOPS 内存带宽。...尽管 PyTorch 是一个活跃关注领域,但 PyTorch 编译器或配置文件 API 并不是最容易使用。 总而言之,发现对系统基本原理理解几乎总是有用,希望这对你也有用。

    50930

    先了解下这个问题第一性原理

    另一方面,如果你正在运行大量矩阵乘法运算(也就是计算紧张时候),将你程序重写成 C++ 去减轻额外开销就不会管用。...但是,为了让你钱从你昂贵矩阵乘法得到回报,你需要减少花费在其他部分时间。 但为什么这里重点是最大化计算,而不是最大化内存带宽?...事实上,归一化运算逐点(pointwise)运算使用 FLOPS 仅为矩阵乘法 1/250 1/700。那为什么矩阵乘法运算会远比它们应该使用运行时间更多呢?...,就可以计算每个 repeat FLOPS 内存带宽。...尽管 PyTorch 是一个活跃关注领域,但 PyTorch 编译器或配置文件 API 并不是最容易使用。 总而言之,发现对系统基本原理理解几乎总是有用,希望这对你也有用。

    55920

    Linux内核14-clone()、fork()vfork()区别

    分析这三个系统调用之前,先来理解一下进程4要素: 执行代码 每个进程或者线程都要有自己执行代码,不论是独立,还是共享一段代码。...其余3个字节是一组标志,如下表所示: 名称描述CLONE_VM共享内存描述符所有的页表CLONE_FS共享文件系统CLONE_FILES共享打开文件CLONE_SIGHAND共享信号处理函数,阻塞挂起信号等...clone()其实是一个C封装函数,它建立新进程栈并调用sys_clone()系统调用。sys_clone()系统调用没有参数fnarg。...下面我们看一个C代码示例,看看clone()函数使用: #include #include #include #include <linux...而现在fork使用了COW机制,唯一代价仅仅是复制父进程页表代价,所以vfork不应该出现在新代码之中。

    1.7K10

    如何在大型代码仓库删掉 6w 行废弃文件 exports?

    作者:ssh,字节跳动 Web Infra 团队成员 本文是最近在公司内部写废弃代码删除工具一篇思考总结,目前多个项目中已经删除约 6w 行代码。...但下面两步依然很棘手,先给出结论: 如何确定步骤 1 变量本文件内部没有用到(作用域分析)?...官方 no-unused-vars 默认是不考虑 export 出去变量,而经过对源码阅读发现,仅仅 修改少量代码 就可以打破这个限制,让 export 出去变量也可以被分析,模块内部是否使用...无用文件删除 之前基于 webpack-deadcode-plugin 做了一版无用代码删除,但是实际使用过程,发现一些问题。...个人把这套代码 fork 下来公司内部大型项目中跑了一下,也确实是内存溢出 ,看了下自动修复方案代码,也都是很常规基于 ts-morph API 调用,猜测是底层 API 性能问题?

    4.7K20

    GPU加速03:多流共享内存—让你CUDA程序如虎添翼优化技术!

    内存优化 本系列第一篇文章提到,CPUGPU组成异构计算架构,如果想从内存上优化程序,我们必须尽量减少主机与设备间数据拷贝,并将更多计算从主机端转移到设备端。...)共享内存(Shared Memory);多个SM可以读取显卡上显存,包括全局内存(Global Memory)。...下文将以矩阵乘法为例,展示如何使用Shared Memory来优化程序。 二维三维执行配置 解释内存优化前,先填一下之前埋下多维执行配置坑。...各个内置变量.x .y.z为不同维度下。...矩阵运算 一个C = AB矩阵乘法运算,需要我们把A某一行与B某一列所有元素一一相乘,求和后,将结果存储到结果矩阵C(row, col)上。

    4.8K20

    进程地址空间

    子进程将g-val进行了修改 输出结果就发现了一个神奇现象: 同一个变量,地址相同,却有两个不同!...这是为什么呢? 这就引出了一个概念: 进程地址空间 上面两段代码结果给出了结论: 变量内容不一样,所以父子进程输出变量绝对不是同一个变量!...为什么要有进程地址空间? 大家可能会有疑惑,为什么要平白无故地创造出一个进程地址空间呢?这不是在在误导我们吗?...那么大家想一想,当我们C语言或者C++,申请一块空间时,是真正直接在物理内存上开辟一块空间吗? 答案是不是!...我们把这种技术叫做延迟分配,这样提高了CPU内存使用效率。 大家都知道,父子进程代码都是共享,父子进程不写入时候数据都是共享,那么当父子进程任意一方需要进行写入时候给如何操作呢?

    7910

    如何在大型代码仓库删掉废弃文件 exports?

    但下面两步依然很棘手,先给出结论: 如何确定步骤 1 变量本文件内部没有用到(作用域分析)?...官方 no-unused-vars 默认是不考虑 export 出去变量,而经过对源码阅读发现,仅仅 修改少量代码 就可以打破这个限制,让 export 出去变量也可以被分析,模块内部是否使用...无用文件删除 之前基于 webpack-deadcode-plugin[10] 做了一版无用代码删除,但是实际使用过程,发现一些问题。...deadcode 模式手动删除 fork-ts-checker-webpack-plugin,这样可以扫描出无用依赖,但是上文中那样从文件只导入类型情况,还是会被认为是无用文件而误删。...个人把这套代码 fork 下来公司内部大型项目中跑了一下,也确实是内存溢出 ,看了下自动修复方案代码,也都是很常规基于 ts-morph API 调用,猜测是底层 API 性能问题?

    4.7K60

    稀疏矩阵之 toarray 方法 todense 方法

    事实上,才开始接触 SciPy 稀疏矩阵时候也曾经把这 2 个方法之间画上等号。但是,两者之间还是存在着很大不同,具体有哪些不同之处我们就首先从返回类型开始说明。...Python C 语言不一样,定义函数时候完全不需要指定返回类型,调用函数时候接收返回变量也同样是完全不需要指定其对应类型。...而不是 b = a 是因为不希望返回参数 a 捆绑在一起(共享同样内存空间,当 n=1 时候就会出现这种情况)。...02 矩阵 矩阵运算之前,我们首先需要看一下通过一个二维数组来构造一个矩阵方法,这样方法有很多,比较推荐去使用 numpy.mat 函数,这个函数接受一个参数,该参数就是二维数组。...结论 在这里,首先通过稀疏矩阵 toarray() 方法以及 todense() 方法返回看似一样但实际上却是两个完全不同实例,然后通过对矩阵运算给出它们两者区别。

    3.6K31

    Im2Col+GEMM改进方法MEC,一种更加高效卷积计算策略

    MEC算法初级版本 我们要结合Figure2来看一下这个伪代码,这里意思就是说: 因为是 卷积,并且滑动步长为 ,所以这里循环取出A,B,C,D,E这5个子矩阵Figure2看),每个子矩阵维度都是...将A,B,C,D,E按照行优先展开并拼成一个大中间矩阵维度是: 。 从L循环取出 , , , , 这 个子矩阵,并计算 次矩阵乘法,就获得了最终输出特征图。...但是这样做可能带来问题是,Im2Col+GEMM一次矩阵乘法现在变成了多次小矩阵乘法,虽然这对并行计算是有利,但如果使用OpenBlas库来计算则失去了它对大矩阵乘法计算优势,所以从工程实现角度来说要达到论文给出...但是,实际操作,子矩阵数量对性能影响是很大Solution1执行了 次gemm,而Solution2执行了 次gemm,如果使用Blas矩阵计算库,那么这两种方法特定硬件平台如GPU...因此,Algorithm2第8行使用了一个参数T来控制是使用Solution1还是Solution2,其中T是一个硬件平台有关参数。论文指出,如果是GPU上,那么T取 是一个不错

    2.3K42

    能「看到」张量运算:​因子图可视化

    尽管我最初是图模型消息传递语境遇到因子图,但我很快就意识到它们体现了一种更通用更简单概念。在这篇文章将主要在高层面介绍因子图,而不会涉及图模型或消息传递等算法具体细节。...矩阵乘法定义, ? 求和符号实际上是多余。我们可以直接舍弃它,并推断出索引 k 必须被求和,因为它没有出现在左侧。 ? 为什么要这么做?...另外,你可以使用 numpy.einsum Python 轻松尝试这些。...因为这能让我们将复杂因子分解转换成更可视化表示,从而更加轻松地处理。numpy 数值张量运算可以很好地适用于这个框架。下面给出了几个无需过多解释示例: 矩阵-向量乘法 ?...作为一个有趣练习,你可以试试解读矩阵乘法(matrix chain multiplication)过程,并使用因子图理解寻找一个链矩阵总计算成本是如何受乘法顺序影响

    1.2K40

    从「根」上找出模型瓶颈!康奈尔AI联合创始人发文,从第一原理出发剖析深度学习

    所以为了钱花,需要尽可能地提升显卡运行效率,不断地让显卡进行矩阵运行。...一篇关于BERT模型flop研究可以发现,BERT99.8%都是矩阵乘法(Tensor Contraction)操作,所以虽然非矩阵乘法速度要慢15倍,但也无伤大雅。...但在这种情况下,归一化点式运算实际上比矩阵乘法运算少了250倍FLOPS700倍FLOPS。...至于为什么矩阵乘法理论性能现实相差这么多,研究人员给出答案是:内存带宽(memory bandwidth)。...像NVFuser这样融合编译器帮助下,实际上可以很容易地测量成本。 以一个PyTorch函数为例,并用融合编译器对其进行基准测试,然后就可以计算出不同重复所达到FLOPS内存带宽。

    46520

    25个机器学习面试题,你能回答几个?

    本文中,作者给出了 25 个非常有意思机器学习面试问题,这些问题都没有给出明确答案,但都有一定提示。读者也可以留言中尝试。 1、 95% 置信区间下构建了一个线性回归模型。...这是否意味着模型参数对于试图近似的函数有 95% 概率是真实估计?...9、 大多数机器学习算法涉及到一些对矩阵操作,例如矩阵乘法求逆矩阵。请给出一个简单数学证明,说明为什么这种机器学习算法 mini-batch 版本可能比整个数据集上进行训练计算效率更高?...请列举一些可能替代反向传播算法来训练神经网络技术。 (提示:随机搜索...) 14、 假设你现在有两个问题(线性回归 logistic 回归)。其中哪一个更有可能从超快大型矩阵乘法算法获益?...请给出简单数学证明,说明为什么在这种情况下,使用最小二乘法构建一个回归模型并不是一个好选择。 (提示:从矩阵代数角度思考...) 19、 请解释,为什么 k 折交叉验证对于时序模型效果并不好。

    1.3K10

    fork函数简介_fork()&&fork()

    (进程id0总是由交换进程使用,所以一个子进程进程id不可能为0)。...fork之后,操作系统会复制一个与父进程完全相同子进程,虽说是父子关系,但是操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立,子进程数据空间中内容是父进程完整拷贝...以上是个人在看了资料后理解总结,可能在细节方面有些问题,欢迎大家指正! fork()子进程与父进程之间文件描述符问题 C程序,文件由文件指针或者文件描述符表示。...一个进程调用fork()函数后,系统先给新进程分配资源,例如存储数据代码空间。然后把原来进程所有都复制到新新进程,只有少数值与原来进程不同。相当于克隆了一个自己。   ...引用一位网友的话来解释fpid为什么父子进程不同。

    1.2K21

    定位并行应用程序可伸缩性问题(最透彻一篇)

    图10乘法函数也执行了同样操作。令人意外是,benchmark测试运行时间并不比不支持NUMA版本好很多,因此让我们使用 VTune 工具对内存访问进行分析(如图11)。...图14 分配函数表示内存对象 很容易确定这三个对象就是a,bc矩阵矩阵c占用存储量最大。...通过用户代码栈,我们可以 Intel VTune Amplifier Source View (如图16)深入到数据分配代码具体行。在这个例子矩阵b数据导致延迟抖动负载增加。...现在,尽管数组数据是CPU绑定过线程中分配初始化,但我们依然需要了解为什么会发生这种情况。 ? 图15 栈窗格内存对象 ?...即使通过之前绑定到CPU核上用来分配矩阵ca线程来访问它们行,这也并不能完全运用到矩阵b。在此算法实现矩阵b一半数据是线程从远程端口读取

    92011

    MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 -- Trap -- 下

    如果父子进程可以共享父级物理内存,则效率会更高。 然而武断地实现这种方法是行不通,因为它会导致父级子级通过对共享写入来中断彼此执行。...由页面错误驱动COW fork可以使父级子级安全地共享物理内存。当CPU无法将虚拟地址转换为物理地址时,CPU会生成页面错误异常。...之所以这些变量要单独列出来,是因为例如你C语言中定义了一个大矩阵作为全局变量,它元素初始都是0,为什么要为这个矩阵分配内存呢? 其实只需要记住这个矩阵内容是0就行。...通常可以调优地方是,有如此多内容全是0page,物理内存只需要分配一个page,这个page内容全是0。然后将所有虚拟地址空间全0page都map到这一个物理page上。...mmap参数,lenflag是什么意思? len是文件你想映射到内存字节数。prot是read/write。flags会在mmap lab中出现,认为它表示了这个区域是私有的还是共享

    38720
    领券