C++矢量运算与java矢量运算

矢量运算

概述

矢量运算是一种基于向量的数学运算,它遵循特定的法则。以下是矢量运算的一些基本原理:

  • 矢量加法:可以使用平行四边形法则或三角形法则来执行。当两个矢量相加时,可以将它们的起点放在同一个点上,然后根据平行四边形法则,从这两个矢量的尾部画两条线,使其首尾相连,形成一个平行四边形。这个平行四边形的对角线即表示两矢量之和。如果使用三角形法则,则是将一个矢量的尾部与另一个矢量的头部相连,形成三角形,再从第一个矢量的起点到第二个矢量的尾部画一条线,这条线代表两矢量之和。
  • 矢量减法:被视作矢量加法的逆运算。从一个矢量中减去另一个矢量相当于加上那个矢量的负矢量。
  • 矢量与标量乘法:将矢量的每个分量乘以标量即可。几何意义上,一个矢量乘以正标量会使得矢量在保持方向不变的情况下扩大若干倍,而乘以负标量则会使矢量的方向反转并等比例缩小。
  • 矢量共线定理:表明如果两个矢量共线,那么其中一个矢量可以表示为另一个矢量与一个标量的乘积。

矢量运算比标量快的原因

  1. 并行性(Parallelism):矢量化操作可以同时对多个数据元素执行相同的操作。现代处理器中的矢量处理单元(如SSE、AVX指令集)可以在单个指令中对多个数据元素执行相同的操作,从而实现并行计算。相比之下,标量操作则需要逐个处理每个数据元素,无法充分利用处理器的并行计算能力。

  2. 数据局部性(Data Locality):矢量化操作可以提高数据的局部性,减少内存访问次数。由于矢量操作一次处理多个数据元素,可以更有效地利用处理器的缓存,降低了内存访问的开销。而标量操作需要对每个数据元素分别进行内存访问,导致更多的缓存未命中和内存带宽瓶颈。

  3. 指令优化(Instruction Optimization):矢量指令集(如SSE、AVX)提供了丰富的指令,能够对矢量数据进行高效的操作,包括加法、乘法、逻辑运算等。处理器可以利用这些指令进行更有效的优化,从而提高运算速度。相比之下,标量指令集的操作对象是单个数据元素,限制了处理器进行指令级并行优化的能力。

  4. 数据重用(Data Reuse):矢量化操作可以更好地利用数据重用的机会。在循环等迭代过程中,矢量化操作可以将多次计算相同的操作合并为一次计算,从而减少了重复计算的开销。而标量操作需要对每个数据元素分别进行计算,无法充分利用数据重用的机会。

C++矢量运算与标量运算的比较

#include <iostream>
#include <vector>
#include <chrono>

int main() {
    std::vector<int> vec1 = {1, 2, 3};
    std::vector<int> vec2 = {4, 5, 6};
    std::vector<int> result(3);

    auto start = std::chrono::high_resolution_clock::now();

    for (size_t i = 0; i < vec1.size(); ++i) {
        result[i] = vec1[i] + vec2[i];
    }

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    std::cout << "Vector addition time: " << elapsed.count() << " seconds" << std::endl;

    int scalar1 = 1;
    int scalar2 = 4;

    start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < 3; ++i) {
        int scalar_result = scalar1 + scalar2;
    }

    end = std::chrono::high_resolution_clock::now();
    elapsed = end - start;
    std::cout << "Scalar addition time: " << elapsed.count() << " seconds" << std::endl;

    return 0;
}

运行结果:

java矢量运算与标量运算的比较

package org.cyl.spaceutils;

import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorSpecies;

public class VectorScalarOperations {
    public static void main(String[] args) {
        // 定义矢量a和b
        float[] a = {1, 2, 3};
        float[] b = {4, 5, 6};
        float[] c=new float[a.length];
        VectorScalarOperations v1=new VectorScalarOperations();
        long startTime = System.nanoTime();
        v1.vectorComputation(a,b,c);
        long endTime = System.nanoTime();
        System.out.println("矢量花费的时间:"+(endTime-startTime));

        long startTime1 = System.nanoTime();
        v1.xadd(a,b,c);
        long endTime1 = System.nanoTime();
        System.out.println("标量花费的时间:"+(endTime1-startTime1));

    }

    static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
    void vectorComputation(float[] a, float[] b, float[] c) {
        int i = 0;
        int upperBound = SPECIES.loopBound(a.length);
        for (; i < upperBound; i += SPECIES.length()) {
            // FloatVector va, vb, vc;
            var va = FloatVector.fromArray(SPECIES, a, i);
            var vb = FloatVector.fromArray(SPECIES, b, i);
            var vc = va.mul(va)
                    .add(vb.mul(vb));
            vc.intoArray(c, i);
        }
    }

    void xadd(float[]a,float[]b,float[]c){
        for (int i=0;i<a.length;i++){
            c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
        }
    }
}

java的要大量数据才能展现出其价值。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【硬件设计】(更新中)以 UCC27710 为例设计栅极驱动器元件选型(资料摘抄)

还没更新完。。。。。。。 【仅作自学记录&#xff0c;不出于任何商业目的。如有侵权&#xff0c;请联系删除&#xff0c;谢谢&#xff01;】 本文摘抄翻译自&#xff1a; Bootstrap Network Analysis: Focusing on the Integrated Bootstrap Functionality (infineon.com)Boo…

[nlp入门论文精读] | Transformer

写在前面 最近工作从CV转向了NLP&#xff0c;于是空余时间便跟着哔哩哔哩李沐老师的视频学习。其实研一NLP课程讲论文的时候&#xff0c;我们小组就选择了经典的Attention和Bert&#xff0c;但还有很多细节并不完全理解&#xff0c;实际使用时也很困惑。 因此这个系列就来记…

【Android 内存优化】KOOM 快手开源框架线上内存监控方案-源码剖析

文章目录 前言OOMMonitorInitTask.INSTANCE.initOOMMonitor.INSTANCE.startLoopsuper.startLoopcall() LoopState.Terminate dumpAndAnalysisdumpstartAnalysisService回到startLoop方法总结 前言 这篇文章主要剖析KOOM的Java层源码设计逻辑。 使用篇请看上一篇: 【Android …

Kubesphere前端项目分析

1 KubeSphere console功能导图 模块&#xff1a; 命令行工具 (kubectl) 日志&#xff08;Logging&#xff09; 平台设置&#xff08;Platform Settings&#xff09; 服务组件&#xff08;Service Components&#xff09; 监控和警报&#xff08;Monitoring & Alerting&…

手写分布式配置中心(六)整合springboot(自动刷新)

对于springboot配置自动刷新&#xff0c;原理也很简单&#xff0c;就是在启动过程中用一个BeanPostProcessor去收集需要自动刷新的字段&#xff0c;然后在springboot启动后开启轮询任务即可。 不过需要对之前的代码再次做修改&#xff0c;因为springboot的配置注入value("…

pytest教程-15-多个fixture以及重命名

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了fixture的yield关键字&#xff0c;本小节我们讲解一下使用多个fixture的方法。 使用多个fixture 如果用例需要用到多个fixture的返回数据&#xff0c;fixture也可以return一个元组、list或字…

[嵌入式系统-37]:龙芯1B 开发学习套件 -7-MIPS指令集

目录 一、MIPS指令分类 二、常用指令详解 三、常用MIPS指令集及格式&#xff1a; 四、CPU内部的32个寄存器&#xff1a; 一、MIPS指令分类 MIPS&#xff08;Microprocessor without Interlocked Pipeline Stages&#xff09;指令集是一种广泛用于教学和嵌入式系统的指令集…

在线部署ubuntu20.04服务器,安装jdk、mysql、redis、nginx、minio、开机自启微服务jar包

一、服务器 1、查看服务器版本 查看服务器版本为20.04 lsb_release -a2、服务器信息 服务器初始账号密码 sxd / 123456 首先,更改自身密码都输入123456 sudo passwd 创建最高权限root账号&#xff0c;密码为 123456 su root 3、更新服务器源 1、更新源列表 sudo apt-g…

【golang】Windows与Linux交叉编译保姆级教程

【golang】Windows与Linux交叉编译 大家好 我是寸铁&#x1f44a; 总结了一篇【golang】Windows与Linux交叉编译的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题背景 今天寸铁想将Windows中的程序部到Linux下跑&#xff0c;我们知道在从Windows与Linux下要进行交叉编译…

11、Linux-安装和配置Redis

目录 第一步&#xff0c;传输文件和解压 第二步&#xff0c;安装gcc编译器 第三步&#xff0c;编译Redis 第四步&#xff0c;安装Redis服务 第五步&#xff0c;配置Redis ①开启后台启动 ②关闭保护模式&#xff08;关闭之后才可以远程连接Redis&#xff09; ③设置远程…

Java基础 - 8 - 算法、正则表达式、异常

一. 算法 什么是算法&#xff1f; 解决某个实际问题的过程和方法 学习算法的技巧&#xff1f; 先搞清楚算法的流程&#xff0c;再直接去推敲如何写算法 1.1 排序算法 1.1.1 冒泡排序 每次从数组中找出最大值放在数组的后面去 public class demo {public static void main(S…

21 easy 1. 两数之和

//给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 // // 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 // // 你可以…

java Spring boot简述jetcache 并叙述后续文章安排

我们之前 讲了 Spring boot 整合 cache 使用 simple(默认) redis Ehcache memcached的几种方式 但是 始终有人觉得不够完善 提出了一些问题 例如 觉得 当前spring boot 对缓存过期的控制过于松散 不严谨 比较明显的体现就是 memcached过期时间在逻辑代码中控制 Ehcache的过期时…

Tomcat的安装

下载Tomcat&#xff08;这里以Tomcat8.5为例&#xff09; 直接进入官网进行下载&#xff0c;Tomcat官网 选择需要下载的版本&#xff0c;点击下载这里一定要注意&#xff1a;下载路径一定要记住&#xff0c;并且路径中尽量不要有中文&#xff01;&#xff01;&#xff01;&…

Prompt Engineering、Finetune、RAG:OpenAI LLM 应用最佳实践

一、背景 本文介绍了 2023 年 11 月 OpenAI DevDay 中的一个演讲&#xff0c;演讲者为 John Allard 和 Colin Jarvis。演讲中&#xff0c;作者对 LLM 应用落地过程中遇到的问题和相关改进方案进行了总结。虽然其中用到的都是已知的技术&#xff0c;但是进行了很好的总结和串联…

神经网络的矢量化,训练与激活函数

我们现在再回到我们的神经元部分&#xff0c;来看我们如何用python进行正向传递。 单层的正向传递&#xff1a; 我们回到我们的线性回归的函数。我们每个神经元通过上述的方法&#xff0c;就可以得到我们的激发值&#xff0c;从而可以继续进行下一层。 我们用这个方法就可以得…

排序算法的对比

类别排序方法时间复杂度空间复杂度稳定性平均情况特殊情况 插入 排序 插入排序基本有序最优稳定希尔排序不稳定 选择 排序 选择排序不稳定堆排序不稳定 交换 排序 冒泡排序稳定快速排序基本有序最差不稳定归并排序稳定基数排序稳定

0环PEB断链实现

截止到昨天那里我们的思路就清晰了&#xff0c;通过EPROCESS找到我们要隐藏的进程的ActiveProcessLinks&#xff0c;将双向链表的值修改&#xff0c;就可以将我们想要隐藏的这个进程的ActiveProcessLinks从双向链表中抹去的效果&#xff0c;这里的话如果在windbg里面直接使用ed…

用Python实现一个简单的——人脸相似度对比

近几年来&#xff0c;兴起了一股人工智能热潮&#xff0c;让人们见到了AI的能力和强大&#xff0c;比如图像识别&#xff0c;语音识别&#xff0c;机器翻译&#xff0c;无人驾驶等等。总体来说&#xff0c;AI的门槛还是比较高&#xff0c;不仅要学会使用框架实现&#xff0c;更…

Day33|贪心算法part3

k次取反后最大的数组元素和 思路&#xff1a;贪心&#xff0c;局部最优&#xff0c;让绝对值大的负数变正数&#xff0c;当前数值达到最大&#xff0c;整体最优&#xff1b;整个数组和达到最大。如果把序列中所有负数都转换为正数了&#xff0c;k还没耗尽&#xff0c;就是k还大…