R语言:鉴于计算10亿以内训练模型记录for循环的加速

news2024/11/17 3:10:21

文章目录

    • 1 前言
    • 2 几个循环
      • 2.1 100以内的和
      • 2.2 100以内奇数和/偶数和
    • 3 多重循环
      • 3.1 向量化
      • 3.2 合并循环
      • 3.3 apply函数
      • 3.4 矩阵运算
      • 3.5 foreach分解任务
    • 4 讨论

1 前言

笔者主力机是MBAM1芯片(8+256),某个下午巩固循环突然思考到个问题,小循环很快就能run出来,中循环还勉勉强强,稍微上点强度就运行的很慢。虽然是CPU占用100%,8颗核心好像是偷着懒跑的,但是丢给我那台4核心8线程黑苹果,是跑满的,说明ARM在多线程的时候,有点东西

下图是计算一个10亿内训练模型时的top

2 几个循环

2.1 100以内的和

### for
sum <- 0
for (i in 1:100) {
  sum <- sum + i
}
print(sum)

### while
sum <- 0
i <- 1
while (i <= 100) {
  sum <- sum + i
  i <- i + 1
}
print(sum)

2.2 100以内奇数和/偶数和

### for
odd_sum <- 0
even_sum <- 0

for (i in 1:100) {
  if (i %% 2 == 0) {
    even_sum <- even_sum + i
  } else {
    odd_sum <- odd_sum + i
  }
}

print(paste("奇数和:", odd_sum))
print(paste("偶数和:", even_sum))

### while
odd_sum <- 0
even_sum <- 0
i <- 1

while (i <= 100) {
  if (i %% 2 == 0) {
    even_sum <- even_sum + i
  } else {
    odd_sum <- odd_sum + i
  }
  i <- i + 1
}

print(paste("奇数和:", odd_sum))
print(paste("偶数和:", even_sum))

3 多重循环

以下仅记录和提供思路,具体情况具体分析,但是有一点思维模式很得益

3.1 向量化

假设计算两个向量x和y的点积,使用for循环分别游历,相乘再相加:

x <- c(1, 2, 3, 4, 5)
y <- c(5, 4, 3, 2, 1)
dot_product <- 0
for (i in 1:length(x)) {
  dot_product <- dot_product + x[i] * y[i]
}
print(dot_product)

向量化,可以理解为对号入座,亮点就是sum()*

x <- c(1, 2, 3, 4, 5)
y <- c(5, 4, 3, 2, 1)
dot_product <- sum(x * y)
print(dot_product)

3.2 合并循环

假设对两个矩阵A和B中的每个元素进行遍历,将它们相加,并将结果保存到矩阵C中。可以使用两个嵌套的for循环实现:

A <- matrix(1:9, 3, 3)
B <- matrix(10:18, 3, 3)
C <- matrix(0, 3, 3)
for (i in 1:nrow(A)) {
  for (j in 1:ncol(A)) {
    C[i, j] <- A[i, j] + B[i, j]
  }
}
print(C)

#输出结果:
     [,1] [,2] [,3]
[1,]   11   13   15
[2,]   17   19   21
[3,]   23   25   27

但是理解这类的目的,合并循环的思路在这里刚好就是矩阵一一对应的数字相加:

A <- matrix(1:9, 3, 3)
B <- matrix(10:18, 3, 3)
C <- A + B
print(C)

3.3 apply函数

假设有一个3x3的二维矩阵mat,需要将矩阵中每个元素求平方。我们可以使用for循环来实现:

mat <- matrix(1:9, 3, 3)
result <- matrix(0, 3, 3)
for (i in 1:nrow(mat)) {
  for (j in 1:ncol(mat)) {
    result[i, j] <- mat[i, j] ^ 2
  }
}
print(result)

apply+function

mat <- matrix(1:9, 3, 3)
result <- apply(mat, c(1, 2), function(x) x^2)
print(result)

3.4 矩阵运算

假设需要计算一个矩阵A的逆矩阵,使用for循环和矩阵运算实现:

A <- matrix(c(1, 2, 3, 4), 2, 2)
det_A <- A[1, 1] * A[2, 2] - A[1, 2] * A[2, 1]
adj_A <- matrix(c(A[2, 2], -A[1, 2], -A[2, 1], A[1, 1]), 2, 2)
A_inv <- adj_A / det_A
print(A_inv)

#输出结果:
     [,1] [,2]
[1,] -2.0  1.0
[2,]  1.5 -0.5

若要优化这一步骤,很简单,直接用solve()

A <- matrix(c(1, 2, 3, 4), 2, 2)
A_inv <- solve(A)
print(A_inv)

3.5 foreach分解任务

foreach包实现多线程for循环

library(foreach)
library(doParallel)

# 创建一个1000行,1000列的矩阵
m <- matrix(runif(1000000), nrow = 1000)

# 初始化并行计算环境
cl <- makeCluster(detectCores())
registerDoParallel(cl)

# 使用foreach包和%dopar%运算符进行并行计算
result <- foreach(i = 1:nrow(m), .combine = "+") %dopar% sum(m[i, ])

# 结束并行计算环境
stopCluster(cl)

# 输出结果
print(result)

有人会说,这不就是用了个函数吗?

是,但又不完全是,不然为何有人懂得用这个函数,但有人需要一步一步算(并非说一步一步算不好,只有自己算过,理解了,才懂得去挖掘深度,化繁为简)

4 讨论

如果只知道个函数是知其然而不知其所以然,但是只知道计算过程便如优化前的一样,一步一步计算。得益于现在互联网发展的飞起,各种便利工具各种开源方法,几乎人人都是调包侠,但是当现成的辅佐无法满足时还是需要回归底层。最近深有感触,不论是数据挖掘、还是机器学习深度学习、人工智能、全栈,分析的尽头就是算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/493198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Luenberger Observer】龙贝格观测器及示例Matlab仿真

目录 龙贝格观测器 龙贝格观测器示例和仿真 Matlab仿真 龙贝格观测器 观测器&#xff1a;根据系统的输入u和输出y估计系统的状态x。 SISO系统的状态空间方程如下 龙贝格观测器&#xff0c;通过在原系统添加基于输出误差校正项&#xff0c;构造状态空间方程&#xff0c;设x_h…

如何用Jmeter压测Netty的Echo服务之自定义Jmeter的Java Sampler

前言 如果想要压测一些三方组件&#xff0c;比如MQ&#xff0c;redis什么的&#xff0c;jmeter本身是不支持的。 本文以开发一个压测netty的echo示例&#xff0c;说明如何自定义jmeter的sampler。 开发 本文以idea示例&#xff0c; 新建工程 打开idea新建一个空的maven工程…

yolov8 ONNX Runtime C++ 部署

其实个人偏爱用OpenCV DNN 部署&#xff0c;但是在前面一篇博客发现还要升级OpenCV。 笔记本的CPU 是AMD 牌子的&#xff0c;就只能用 ONNX Runtime 部署了。 目录 Pre: cv::dnn::blobFromImages() gettimeofday() rand() template 代码 utils.h utils.cpp detect.h…

uboot第一阶段 start.S代码分析

u-boot.lds中找到start.S入口 (1)C语言规定整个项目的入口就是main函数。 (2)在uboot中因为有汇编阶段参与&#xff0c;因此不能直接找main.c。整个程序的入口取决于链接脚本中ENTRY声明的地方。ENTRY(_start)因此定义_start符号 的文件就是整个程序的起始文件&#xff0c;即st…

python报错提示以及logger的一些应用

本篇是拆解这篇【python︱函数、for、if、name、迭代器、防范报错、类定义、装饰器、argparse模块、yield 】 将报错 logger提示拿出来 文章目录 1、防范报错1.1 assert 断言 2 try...except...报错并提示异常信息优雅的异常报错&#xff1a;suppress 3、报错日志记录&#xf…

【Java 并发编程】一文详解 Java 内置锁 synchronized

一文详解 Java 内置锁 synchronized 1. 前言1.1 并发编程中存在线程安全问题1.2 设计同步器的意义1.3 如何解决线程并发安全问题&#xff1f; 2. synchronized 的用法2.1 修饰实例方法&#xff0c;锁是当前实例对象2.2 修饰静态方法&#xff0c;锁是当前类对象2.3 修饰代码块&a…

简单创建SSM项目

1、在idea中创建项目 点击new-project&#xff0c;点击Maven项目&#xff0c;勾选 creat from archetype &#xff0c;找到maven-archetype-webapp 写好相关信息 点击下一步&#xff0c;需要检查maven环境 点击后下载对应的插件&#xff0c;选择项目地址。 开始下载资源&#x…

rust vscode编辑器常用插件与配置

插件&#xff1a;rust-analyzer 会实时编译和分析你的 Rust 代码&#xff0c;提示代码中的错误&#xff0c;并对类型进行标注 插件的完整手册地址&#xff1a;https://rust-analyzer.github.io/manual.html。 插件&#xff1a; rust syntax 为代码提供语法高亮。 …

就挺无语的,这是有脾气的博客

文章目录 前言1. 背景2. 使用3. 公众号体验4. 结束语 前言 ChatGPT已经推出两个多月了&#xff0c;热度已经不减。ChatGPT由人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型&#xff0c;一款人工智能技术驱动的自然语言处理工具。它能够通过学习和理解人类的…

大厂都用DevOps!十分钟带你了解自动化在DevOps中的运用

Hi&#xff0c;大家好。DevOps、CI/CD、Docker、Kubernetes……好像全世界都在谈论这些技术&#xff0c;以至于你觉得即将到达NoOps阶段。别担心&#xff0c;在工具和各种最佳实践的浩瀚海洋中感到迷失是正常的&#xff0c;是时候让我们来分析一下DevOps到底是什么了。 一、De…

JAVA类加载机制

在Java的世界里&#xff0c;每一个类或者接口&#xff0c;在经历编译器后&#xff0c;都会生成一个个.class文件。 类加载机制指的是将这些.class文件中的二进制数据读入到内存中&#xff0c;并对数据进行校验&#xff0c;解析和初始化。最终&#xff0c;每一个类都会在方法区保…

ChatGPT - 学习和提高新技能的Prompt

文章目录 Prompt例子 Prompt “我想学习/提高[技能]。我是一个完全的初学者。创建一个30天的学习计划&#xff0c;可以帮助像我这样的初学者学习和提高这项技能。”例子 我想学习/提高Flink。我是一个完全的初学者。 创建一个30天的学习计划&#xff0c;可以帮助像我这样的初…

Xilinx Artix-7【XC7A35T-2CSG324I】【XC7A35T-1CSG324I】成本与收发器优化的FPGA器件

产品介绍&#xff1a; Xilinx Artix -7系列 FPGA 重新定义了成本敏感型解决方案&#xff0c;功耗比上一代产品降低了一半&#xff0c;同时为高带宽应用提供一流的收发器和信号处理能力。这些设备基于 28 纳米 HPL 工艺构建&#xff0c;提供一流的性能功耗比。与 MicroBlaze™ 软…

boot-admin整合Liquibase实现数据库版本管理

Liquibase 和 Flyway 是两款成熟的、优秀的、开源/商业版的数据库版本管理工具&#xff0c;鉴于 Flyway 的社区版本对 Oracle 数据库支持存在限制&#xff0c;所以 boot-admin 选择整合 Liquibase 提供数据库版本管理能力支持。 Liquibase 开源版使用 Apache 2.0 协议。 Liqui…

实现服务器版本---表白墙(Servlet)

目录 一、创建Servlet项目 二、约定前后端交互接口 三、前端代码 四、后端代码 五、效果演示 结合Servlet API &#xff0c;实现一个服务器版本表白墙。实现的这个表白墙&#xff0c;就通过服务器来保存这里的消息数据&#xff0c;进而做到 “持久化” 存储。 一、创建Se…

浮点数中的阶码和尾数

阶码和尾数 阶码尾数浮点数浮点数表示示例 例题分析总结 阶码 在机器中表示一个浮点数时需要给出指数&#xff0c;这个指数用整数形式表示&#xff0c;这个整数叫做阶码。 尾数 常用对数的小数部分&#xff0c;用于科学计数法&#xff0c;其表示方法为:Mantissa x Base^Expo…

k210单片机的串口交互实验

先来看看实验的结果吧&#xff0c;k210的9口为RX&#xff0c;10口为TX。接线&#xff1a; 9口接usb转ttl的TX 10口接usb转ttl的RX 下面介绍一下k210需要使用的模块&#xff1a; K210 一共有 3 个串口&#xff0c;每个串口可以自由映射引脚。 例&#xff1a; # IO10→RX1&#…

JuiceFS__持久化缓存源码走读

JuiceFS__持久化缓存源码走读 JuiceFS 是一款高性能 POSIX 文件系统&#xff0c;针对云原生环境特别优化设计&#xff0c;在 Apache 2.0 开源协议下发布。使用 JuiceFS 存储数据&#xff0c;数据本身会被持久化在对象存储&#xff08;例如 Amazon S3&#xff09;&#xff0c;而…

java小记 2023-05-05

public class Test {/*** 谓类的方法就是指类中用static 修饰的方法&#xff08;非static 为实例方法&#xff09;&#xff0c;比如main 方法&#xff0c;那么可以以main* 方法为例&#xff0c;可直接调用其他类方法&#xff0c;必须通过实例调用实例方法&#xff0c;this 关键…

7.3 有源滤波电路(2)

四、开关电容滤波器 开关电容电路由受时钟脉冲信号控制的模拟开关、电容器和运算放大电路三部分组成。这种电路的特性与电容器的精度无关&#xff0c;而仅与各电容器电容量之比的准确性有关。在集成电路中&#xff0c;可以通过均匀地控制硅片上氧化层的介电常数及其厚度&#…