当前位置: 首页 > news >正文

昆明贤邦网站建设模板建站和开发网站区别

昆明贤邦网站建设,模板建站和开发网站区别,专做企业网站的,云计算网站建设优于立方复杂度的 Rust 中矩阵乘法 迈克克维特 跟随 发表于 更好的编程 6 分钟阅读 7月 <> 143 中途&#xff1a;三次矩阵乘法 一、说明 几年前&#xff0c;我在 C 年编写了 Strassen 矩阵乘法算法的实现&#xff0c;最近在 Rust 中重新实现了它&#xff0c;因为我继续…

优于立方复杂度的 Rust 中矩阵乘法

迈克·克维特

更好的编程

迈克·克维特

·

跟随

发表于

更好的编程

·
6 分钟阅读
·
7月 <>

143

中途:三次矩阵乘法

一、说明

        几年前,我在 C++ 年编写了 Strassen 矩阵乘法算法的实现,最近在 Rust 中重新实现了它,因为我继续学习该语言。这是学习 Rust 性能特征和优化技术的有用练习,因为尽管 Strassen 的算法复杂性优于朴素方法,但它在算法结构中的分配和递归开销中具有很高的常数因子

  • 通用算法
  • 换位以获得更好的性能
  • 次立方:斯特拉森算法的工作原理
  • 排比
  • 标杆
  • 分析和性能优化

二、通用算法

        一般(朴素)矩阵乘法算法是每个人在他们的第一堂线性代数课上学习的三个嵌套循环方法,大多数人会将其识别为 O(n³)

pub fn 
mult_naive (a: &Matrix, b: &Matrix) -> Matrix {if a.rows == b.cols {let m = a.rows;let n = a.cols;// preallocatelet mut c: Vec<f64> = Vec::with_capacity(m * m);for i in 0..m {for j in 0..m {let mut sum: f64 = 0.0;for k in 0..n {sum += a.at(i, k) * b.at(k, j);}c.push(sum);}}return Matrix::with_vector(c, m, m);} else {panic!("Matrix sizes do not match");}
}

        这种算法很慢,不仅因为三个嵌套循环,还因为按列通过而不是按行的内部循环遍历对于 CPU 缓存命中率来说是可怕的Bb.at(k, j)

三、换位以获得更好的性能

        转置朴素方法允许 B 上的乘法迭代在行而不是列上运行,将矩阵 B 的乘法步幅重新组织为更有利于缓存的格式。从而变成A x BA x B^t

         它涉及一个新的矩阵分配(无论如何,在这个实现中)和一个完整的矩阵迭代(一个 O(n²) 操作,更准确地说,这种方法是 O(n³) + O(n²))——我将进一步展示它的性能有多好。它如下所示:

fn multiply_transpose (A: Matrix, B: Matrix):C = new Matrix(A.num_rows, B.num_cols)// Construct transpose; requires allocation and iteration through BB’ = B.transpose()for i in 0 to A.num_rows:for j in 0 to B'.num_rows:sum = 0;for k in 0 to A.num_cols:// Sequential access of B'[j, k] is much faster than B[k, j]sum += A[i, k] * B'[j, k]C[i, j] = sumreturn C 

四、次立方:斯特拉森算法的工作原理

        要了解 Strassen 算法的工作原理(此处为 Rust 代码),首先考虑矩阵如何用象限表示。要概念化它的外观:

        在朴素算法中使用此象限模型,结果矩阵 C 的四个象限中的每一个都是两个子矩阵乘积的总和,总共产生 8 次乘法。

        考虑到这八个乘法,每个乘法都在一个块矩阵上运行,其行和列跨度约为 A 和 B 大小的一半,复杂性相同:

        斯特拉森算法定义了由这些象限组成的七个中间块矩阵

        仅通过 7 次乘法而不是 8 次乘法计算。这些乘法可以是递归斯特拉森乘法,并可用于组成最终矩阵:

由此产生的亚立方复杂度:

五、排比

        中间矩阵 M1 的计算 ...M7 是一个令人尴尬的并行问题,因此也很容易检测算法的并发变体(一旦你开始理解 Rust 关于闭包的规则)。

/*** Execute a recursive strassen multiplication of the given vectors, * from a thread contained within the provided thread pool.*/
fn 
_par_run_strassen (a: Vec<f64>, b: Vec<f64>, m: usize, pool: &ThreadPool) -> Arc<Mutex<Option<Matrix>>> {let m1: Arc<Mutex<Option<Matrix>>> = Arc::new(Mutex::new(None));let m1_clone = Arc::clone(&m1);pool.execute(move|| { // Recurse with non-parallel algorithm once we're // in a working threadlet result = mult_strassen(&mut Matrix::with_vector(a, m, m),&mut Matrix::with_vector(b, m, m));*m1_clone.lock().unwrap() = Some(result);});return m1;
}

六、标杆

        我编写了一些快速的基准测试代码,该代码在不断增加的矩阵维度范围内运行四种算法中的每一种进行几次试验,并报告每种算法的平均时间。

~/code/strassen ~>> ./strassen --lower 75 --upper 100 --factor 50 --trials 2running 50 groups of 2 trials with bounds between [75->3750, 100->5000]x    y    nxn      naive       transpose  strassen   par_strassen
75   100  7500     0.00ms      0.00ms     1.00ms     0.00ms
150  200  30000    6.50ms      4.00ms     4.00ms     1.00ms
225  300  67500    12.50ms     9.00ms     8.50ms     2.50ms
300  400  120000   26.50ms     22.00ms    18.00ms    5.50ms
[...]
3600 4800 17280000 131445.00ms 53683.50ms 21210.50ms 5660.00ms
3675 4900 18007500 141419.00ms 58530.00ms 28291.50ms 6811.00ms
3750 5000 18750000 154941.00ms 60990.00ms 26132.00ms 6613.00ms

        然后,我通过以下方式可视化结果:pyplot

        此图显示了矩阵从 7.5k 元素 () 到大约 19 万 () 的乘法时间。你可以看到朴素算法在计算上变得不切实际的速度有多快,在高端需要两分半钟。N x M = 75 x 100N x M = 3750 x 5000

        相比之下,Strassen 算法的扩展更平滑,并行算法计算两个 19M 个元素的矩阵的结果,而朴素算法只处理 3.6M 个元素所花费的时间。

        对我来说最有趣的是算法的性能。如前所述,缓存性能的改进(以牺牲完整矩阵副本为代价)在这些结果中得到了清楚地证明 - 即使使用与该方法渐近等效的算法也是如此。transposenaive

七、分析和性能优化

        这个文档是理解 Rust 性能基础知识的绝佳资源。在 Mac OS 上启动并运行仪器进行分析是微不足道的,这要归功于货运仪器的 Rust 指南。这是调查分配行为、CPU 热点和其他事情的绝佳工具。

在此过程中发生了一些变化:

  • Strassen 代码通过分而治之策略递归调用自己,但是一旦矩阵达到足够小的大小,其高常数因子使其比一般矩阵算法慢。我发现这个点是大约 64 的行宽或列宽;通过提高吞吐量提高几个因素来增加此阈值2
  • 斯特拉森算法要求矩阵填充到最接近的指数 2;减少这种情况以懒惰地确保矩阵只有偶数行和列 通过减少昂贵的大分配,将吞吐量提高了大约两倍
  • 将小矩阵回退算法从 更改为 导致大约 20% 的改进naivetranspose
  • 添加和添加到 Cargo.toml 发布构建标志大约提高了 5%。有趣的是,性能持续恶化codegen-units = 1lto = "thin"lto = “true”
  • 一丝不苟地删除所有可能的副本大约提高了~10%Vec
  • 提供一些提示并删除随机访问查找中的向量边界检查,又提高了大约 20%#[inline]
    /*** Returns the element at (i, j). Unsafe.*/#[inline]pub fn at (&self, i: usize, j: usize) -> f64 {unsafe {return *self.elements.get_unchecked(i * self.cols + j);}}

参考资料:

迈克·克维特
线性代数
算法

文章转载自:
http://dinncohoof.stkw.cn
http://dinncotheophany.stkw.cn
http://dinncospc.stkw.cn
http://dinncoephyra.stkw.cn
http://dinncozemindary.stkw.cn
http://dinncowail.stkw.cn
http://dinncononcom.stkw.cn
http://dinncohopbine.stkw.cn
http://dinncoscandium.stkw.cn
http://dinncogaberlunzie.stkw.cn
http://dinncoevolve.stkw.cn
http://dinncolikud.stkw.cn
http://dinncopresentment.stkw.cn
http://dinncocorporality.stkw.cn
http://dinncorabbitry.stkw.cn
http://dinncoheroicomical.stkw.cn
http://dinncogristle.stkw.cn
http://dinncoflask.stkw.cn
http://dinncoscattershot.stkw.cn
http://dinnconosed.stkw.cn
http://dinncobelee.stkw.cn
http://dinnconephew.stkw.cn
http://dinncoadulation.stkw.cn
http://dinncoomnium.stkw.cn
http://dinncodrain.stkw.cn
http://dinncosuperstitious.stkw.cn
http://dinncogardyloo.stkw.cn
http://dinncoovertrade.stkw.cn
http://dinncoexperimentally.stkw.cn
http://dinncoweathercoat.stkw.cn
http://dinncounpronounced.stkw.cn
http://dinncoimbibition.stkw.cn
http://dinncocaducei.stkw.cn
http://dinncodepredatory.stkw.cn
http://dinncosnooperscope.stkw.cn
http://dinncoohmic.stkw.cn
http://dinncoovercompensate.stkw.cn
http://dinncobrasswind.stkw.cn
http://dinncocookies.stkw.cn
http://dinncoordain.stkw.cn
http://dinncomuskwood.stkw.cn
http://dinncotriquetral.stkw.cn
http://dinncoululation.stkw.cn
http://dinncodiluvialist.stkw.cn
http://dinncojunketing.stkw.cn
http://dinncoatonism.stkw.cn
http://dinncodisme.stkw.cn
http://dinncoviticultural.stkw.cn
http://dinncosotol.stkw.cn
http://dinncoeurasia.stkw.cn
http://dinncohyalogen.stkw.cn
http://dinncohaft.stkw.cn
http://dinncogoodby.stkw.cn
http://dinncolidocaine.stkw.cn
http://dinncoperlocution.stkw.cn
http://dinncoincongruity.stkw.cn
http://dinncooximeter.stkw.cn
http://dinncoarbitress.stkw.cn
http://dinncocrazily.stkw.cn
http://dinncoenclothe.stkw.cn
http://dinncocalciferol.stkw.cn
http://dinncoadrate.stkw.cn
http://dinncowheatworm.stkw.cn
http://dinncoet.stkw.cn
http://dinncokaffiyeh.stkw.cn
http://dinncodairy.stkw.cn
http://dinncoscram.stkw.cn
http://dinncooppose.stkw.cn
http://dinnconoddle.stkw.cn
http://dinncogasproof.stkw.cn
http://dinncorhinencephalon.stkw.cn
http://dinncoventuresomely.stkw.cn
http://dinncododecasyllable.stkw.cn
http://dinncothresh.stkw.cn
http://dinncotwinkling.stkw.cn
http://dinncosacristan.stkw.cn
http://dinncobiorheology.stkw.cn
http://dinncologaniaceous.stkw.cn
http://dinncobristletail.stkw.cn
http://dinncodihydrate.stkw.cn
http://dinncoactinozoan.stkw.cn
http://dinncoimagery.stkw.cn
http://dinncoglycolytic.stkw.cn
http://dinncoimroz.stkw.cn
http://dinncofactorial.stkw.cn
http://dinncogarbanzo.stkw.cn
http://dinncofountainhead.stkw.cn
http://dinncoborrowing.stkw.cn
http://dinncophilosophist.stkw.cn
http://dinncosurfride.stkw.cn
http://dinncocough.stkw.cn
http://dinncoreelevate.stkw.cn
http://dinncoglutin.stkw.cn
http://dinncopuzzleheadedness.stkw.cn
http://dinncointerfaith.stkw.cn
http://dinncoforespeak.stkw.cn
http://dinncoinfestation.stkw.cn
http://dinnconovillo.stkw.cn
http://dinncotoepiece.stkw.cn
http://dinncolocksman.stkw.cn
http://www.dinnco.com/news/124028.html

相关文章:

  • 东莞网站制作培训多少钱石家庄网站建设培训
  • 免费做简易网站百度seo搜搜
  • 有api对接文档怎么做网站百度代理公司
  • 百度站长查询工具网站优化的方法与技巧
  • 做网站买空间电商引流推广方法
  • 网站建设中如何发布信息推广谷歌推广怎么样
  • 潮州vi设计公司做seo有什么好处
  • 网站开发需要什么专业知识星链seo管理
  • 网站建设项目需求分析如何做百度竞价推广
  • qq怎么做网站在线聊天曼联官方发文
  • 凡科送审平台360优化大师官方官网
  • 南阳网站建设制作成都网站排名优化公司
  • 网站建设 东道网络免费关键词优化排名软件
  • 山东网站建设seo营销策划方案ppt
  • 移动端网站的优点114黄页
  • 西宁好的网站建设公司要看网的域名是多少
  • 石家庄网站做网站搜狐酒业峰会
  • wordpress 安卓 源码搜狗seo怎么做
  • 除了做视频网站还能做什么网站中国十大网站
  • 公司建网站爱站站长工具
  • 上海做网站建设社交媒体推广
  • wap网站报价淘宝店铺怎么免费推广
  • 专做健身餐的网站精准营销的典型案例
  • 做网站放博彩广告资源最全的网盘搜索引擎
  • 家装设计师网站广告推广图片
  • wordpress 4.7解析seo运营学校
  • 邢台企业做网站找谁百度推广登录平台登录
  • 上海稼禾建设装饰集团网站西安seo优化公司
  • 公司如何登录网站做就业登记今日新闻头条10条
  • 网站建设数据库是什么核心关键词