-
简介鲲鹏BoostKit分布式存储压缩算法(以下简称“压缩算法”)是华为自研无损压缩算法。相对于开源压缩算法,压缩算法压缩率更高,性能更好。与主流开源压缩算法相比,压缩率可提升25%,带宽性能提升10%。安全加固声明建议关注Ceph官网和Ceph官方Github上的漏洞信息,按照需求及时地进行漏洞修复。环境要求由于压缩算法是华为自研闭源算法,算法仅支持华为鲲鹏处理器使用。硬件要求项目描述CPU型号华为鲲鹏920处理器服务器型号TaiShan 200服务器(型号2280)TaiShan 200服务器(型号5280)软件要求项目描述OSCentOS Linux release 7.6.1810openEuler 20.03 LTS SP1ZSTDZSTD-1.4.5GCCgcc version 4.8.5 或 gcc version 7.3.0编译压缩算法1. 下载压缩算法安装包:下载压缩算法安装包_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译压缩算法_华为云 (huaweicloud.com)2. 获取编译依赖:获取编译依赖_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译压缩算法_华为云 (huaweicloud.com)3. 编译动态库: 编译动态库_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译压缩算法_华为云 (huaweicloud.com)4. 生成压缩算法RPM包: 生成压缩算法RPM包_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译压缩算法_华为云 (huaweicloud.com)编译部署Ceph1. Ceph源码合入压缩算法特性: Ceph源码合入压缩算法插件_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译部署Ceph_华为云 (huaweicloud.com)2. 编译Ceph并验证: 编译Ceph并验证_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译部署Ceph_华为云 (huaweicloud.com)3. 生成Ceph RPM包: 生成Ceph RPM包_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译部署Ceph_华为云 (huaweicloud.com)4. 部署Ceph集群: 部署Ceph集群_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_编译部署Ceph_华为云 (huaweicloud.com)使能压缩算法1. 块存储使能: 块存储使能_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_使能压缩算法_华为云 (huaweicloud.com)2. 对象存储使能: 对象存储使能_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_使能压缩算法_华为云 (huaweicloud.com)验证压缩算法1. 块存储压缩验证: 块存储压缩验证_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_验证压缩算法_华为云 (huaweicloud.com)2. 对象存储压缩验证: 对象存储压缩验证_鲲鹏BoostKit分布式存储使能套件_特性指南_压缩算法 特性指南_验证压缩算法_华为云 (huaweicloud.com)补丁升级获取补丁文件。方式一:华为企业网站下载glz-1.0.0-centos.aarch64-patch.zip方式二:华为运营商网站下载glz-1.0.0-centos.aarch64-patch.zip解压补丁文件。unzip glz-1.0.0-centos.aarch64-patch.zip 按照编译动态库重新编译生成动态库。替换动态库。mv libglz.so /usr/lib64/libglz.so
-
近日,谐云容器云平台(观云台)获得鲲鹏Validated认证。此次谐云联合浙江鲲鹏生态创新中心基于鲲鹏硬件、银河麒麟操作系统 V10、鲲鹏应用使能套件BoostKit对谐云容器云平台解决方案(观云台)进行了深度调优,实现MySQL性能提升96%。降低运营成本和风险的同时,获得更高的运维效率,保障业务稳定运行和高效迭代  此次通过鲲鹏Validated认证的容器云平台,是一款基于Docker和Kubernetes技术构建的一套完整IT标准化和自动化框架,链接底层IT硬件设备设施和上层业务应用,为企业面向业务的敏捷开发和高效运维平台提供平台化支持,在通信、能源、金融等多个行业都有广泛应用。 早在2018年下半年,谐云就携手某在线服务公司启动了数据库、中间件基于ARM服务器的容器化投产方案研究,由于数据库、中间件容器化对存储性能、网络性能要求较高,具有以下几个层面的技术要求: ❖ 低延迟:中间件服务,尤其以数据库类、消息类为主,这两类中间件对延迟要求非常高,在一些呼叫、响应、坐席接入等场景要求更高,而这一挑战对于容器化中间件是最难的地方; ❖ 高带宽:大多中间件均具有高IO特征,因此,对于其系统带宽也有较高的要求; ❖ 无抖动:对网络抖动要求较高,需要网络基本无抖动。 因此,谐云结合其业务场景,经过三年多的技术沉淀,采用了基于MacVLAN的二层高性能网络方案,在社区版本基础上进行深度定制,性能几乎零损耗,达到了和物理网卡相近的性能。并最终创新性的在ARM服务器之上支撑了MySQL数据库、Redis缓存、RocketMQ消息和Elasticsearch搜索引擎的容器化集群部署上线。目前中移投产规模已达500+物理服务器,基本覆盖现有业务对于中间件的开箱即用需求。 #### 性能优势 此次联合浙江鲲鹏生态创新中心深度优化后的谐云容器云平台解决方案(观云台),实现MySQL性能提升96%,Elasticsearch组件在8C32G3实例场景下性能提升48%,业务数据的读写等混合场景性能提升21.53%,拥有低成本、低风险、高运维效率、高资源利用率等性能优势。  ##### 1 MySQL性能 基于Kubernetes部署MySQL,用Sysbench测试工具对MySQL数据库进行性能测试,衡量指标每秒事务数。  ##### 2 Elastcsearch组件性能 基于Kubernetes上部署Elasticsearch,通过Elasticsearch官方提供的Benchmarkrally脚本,模拟在8C32G3实例的场景下,衡量指标ES的写入性能,使用鲲鹏服务器后,经过测试对比,性能提高48%。  ##### 3 业务场景查询性能 基于Kubernetes上,对MySQL使用华为鲲鹏SSD锁优化后,基于Jmeter 测试工具,针对银行卡挂失的登记业务模拟测试数据进行测试,MySQL的QPS和TPS对业务数据的读写等混合场景性能提升21.53%。  谐云作为鲲鹏计算重要的优质伙伴,与鲲鹏携手积极打造技术生态。此前已通过鲲鹏TaiShan服务器认证,实现了与鲲鹏生态系统的良好融合,实现信创云产业全方位布局。 未来,双方将进一步实现在业务和技术等多方面的合作,为客户提供更多的联合解决方案,共同推进我国各行各业数字化转型。 关于谐云 谐云作为国内为数不多掌握底层核心技术的容器云产品及解决方案提供商,以“底层核心技术 + 超前发展理念”致力于为企业数字化转型提供最佳解决方案,拥有丰富的行业落地经验和实施经验。目前已服务百余家客户,覆盖通信、金融、能源、化工等多个行业,为众多行业头部客户企业提供包含建云、上云、用云和管云的全生命周期一站式云原生整体解决方案服务支撑。
-
[root@test build]# ../configure --target-list=aarch64-softmmu-bash: ../configure: /bin/sh^M: bad interpreter: No such file or directory[root@test build]# chmod +x ../configure[root@test build]# ../configure --target-list=aarch64-softmmu-bash: ../configure: /bin/sh^M: bad interpreter: No such file or directory
-
比如一个软件在x86架构下需要50个vCPU能正常运行,那在鲲鹏架构下,大概需要多少vCPU才能正常运行呢?
-
介绍智能写Cache(Smart Write Cache)包含Bcache内核补丁以及相关配套的工具两部分。智能写Cache通过IO直通、Bcache QoS策略控制、Writeback策略控制以及GC策略控制来提升Bcache性能,最终达到提升Ceph集群性能的目的。安全加固声明建议关注Ceph官网和Ceph官方Github上的漏洞信息,按照需求及时地进行漏洞修复。兼容规格硬件兼容列表兼容项目兼容性规格描述CPU型号华为鲲鹏916处理器华为鲲鹏920处理器服务器型号TaiShan 100系列服务器TaiShan 200服务器(型号2280)TaiShan 200服务器(型号5280)软件兼容列表软件名称软件版本OSopenEuler-20.03-LTS-SP1内核版本4.19.90-2012.4.0.0053.oe1CephCeph 14.2.x适用场景智能写Cache是在使用Bcache设备做为Ceph OSD的存储场景下,对其中的Ceph IO流程进行了优化,仅对采用BlueStore存储引擎的OSD有效,考虑到实际应用中Ceph集群中OSD的增加与修改操作,工具需要获取集群内的OSD信息,因此需要保证OSD部署路径使用官方默认路径“/var/lib/ceph/osd”,如果采用其他路径则不会进行优化。说明:Ceph存储场景介绍如下:均衡型:集群采用SSD盘和HDD盘混合部署OSD,使用SSD盘存储OSD的元数据(DB)、日志数据(WAL),使用HDD盘存储真实数据(Data)。全闪存:集群采用全SSD盘部署OSD,OSD的Data、DB、WAL一起存储在SSD盘中。冷存储:集群采用全HDD盘部署OSD,OSD的Data、DB、WAL一起存储在HDD盘中。Bcache:将SSD与HDD绑定为一个Bcache分区,SSD做为HDD的缓存,集群采用Bcache分区部署OSD,OSD的Data存储在Bcache分区中,DB和WAL存放在单独的NVMe分区。目前智能写Cache只对Bcache场景有效。openEuler-20.03-LTS-SP1的内核默认为64K PAGESIZE,智能写Cache工具需要运行在4K PAGESIZE环境下。为方便使用,本文提供两种方式供选择:环境为64K PAGESIZE,需要重新编译替换整个内核,可以选择内核与bcache同时编译安装的方式,请参见“内核编译与安装”。环境已为4K PAGESIZE(通过"getconf PAGESIZE"查询),仅需要安装替换bcache.ko时,可以选择单独编译bcache.ko安装的方式,请参见“Bcache编译与安装”使用指导1. 安装Bcache 1)内核编译与安装:https://support.huaweicloud.com/fg-kunpengsdss/kunpengswceuler_20_0006.html 2)Bcache编译与安装:https://support.huaweicloud.com/fg-kunpengsdss/kunpengswceuler_20_0007.html2. 安装智能写cache工具 https://support.huaweicloud.com/fg-kunpengsdss/kunpengswceuler_20_0008.html3. 安装Bcache-tools工具 https://support.huaweicloud.com/fg-kunpengsdss/kunpengswceuler_20_0009.html4. Ceph使能智能写cache https://support.huaweicloud.com/fg-kunpengsdss/kunpengswceuler_20_0010.html
-
简介InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据。而InfluxDB自带的各种特殊函数如求标准差,随机取样数据,统计数据变化比等,使数据统计和实时分析变得十分方便。安装依赖库yum install -y wget vim openssl openssl-devel curl curl-devel expat expat-devel gcc.aarch64 gcc-c++.aarch64 gcc-gfortran.aarch64 libgcc.4 tcl gettext #能访问互联网,或是有epel源,可直接yum安装go、git。yum install -y epel-release yum install -y golanggo version #centos7.6默认版本1.13git --version #centos7.6默认版本1.8.3.1安装gitwget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.28.0.tar.gztar -zxvf git-2.28.0.tar.gz -C /opt/ && cd /opt/git-2.28.0/编译:./configuremake prefix=/usr/local all安装到/usr/local/bin :make prefix=/usr/local install验证git版本:ln -s /usr/local/bin/git /usr/bin/git --version 安装gowget https://studygolang.com/dl/golang/go1.14.6.linux-arm64.tar.gz tar -zxvf go1.14.6.linux-arm64.tar.gz -C /usr/local/ln -sf /usr/local/go/bin/{go,gofmt} /usr/bin/go version安装influxdb可以将dep通俗的理解为go语言的依赖管理工具,类似于python中的pip,java中的Maven以及node.js中的npm工具通过以下命令来安装depgo get github.com/golang/dep/cmd/depgo get github.com/influxdata/influxdb#若出现类似下图错误,由网络问题导致cd /root/go/src/mkdir -p golang.org/x/cd golang.org/x/git clone https://github.com/golang/xerrors.git###########################################################################cd /root/go/src/github.com/influxdata/influxdbgit checkout 1.8git pull vim build.py #将521、522行注释或删除python build.py如果您使用的 Go 版本是 1.13 及以上 (推荐):go env -w GO111MODULE=ongo env -w GOPROXY=https://goproxy.io,direct如果您使用的 Go 版本是 1.12 及以下:# 启用 Go Modules 功能export GO111MODULE=on# 配置 GOPROXY 环境变量export GOPROXY=https://goproxy.io############################################################安装成功后,指令存放在./build目录下
-
【功能模块】鲲鹏920麒麟linux valgrind【操作步骤&问题现象】鲲鹏920麒麟linux valgrind安装glibc-debuginfo还是用不了 【截图信息】【日志信息】(可选,上传日志内容或者附件)yum install glibc-debuginfoLast metadata expiration check: 0:19:44 ago on 2022年03月09日 星期三 13时03分49秒.Package glibc-debugutils-2.28-36.1.ky10.aarch64 is already installed.Dependencies resolved.Nothing to do.Complete!valgrind --tool=memcheck --trace-children=no --leak-check=no --track-origins=yes maServer==28803== Memcheck, a memory error detector==28803== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.==28803== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info==28803== Command: maServer==28803== valgrind: Fatal error at startup: a function redirectionvalgrind: which is mandatory for this platform-tool combinationvalgrind: cannot be set up. Details of the redirection are:valgrind: valgrind: A must-be-redirected functionvalgrind: whose name matches the pattern: strlenvalgrind: in an object with soname matching: ld-linux-aarch64.so.1valgrind: was not found whilst processingvalgrind: symbols from the object with soname: ld-linux-aarch64.so.1valgrind: valgrind: Possible fixes: (1, short term): install glibc's debuginfovalgrind: package on this machine. (2, longer term): ask the packagersvalgrind: for your Linux distribution to please in future ship a non-valgrind: stripped ld.so (or whatever the dynamic linker .so is called)valgrind: that exports the above-named function using the standardvalgrind: calling conventions for this platform. The package you needvalgrind: to install for fix (1) is calledvalgrind: valgrind: On Debian, Ubuntu: libc6-dbgvalgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfovalgrind: valgrind: Note that if you are debugging a 32 bit process on avalgrind: 64 bit system, you will need a corresponding 32 bit debuginfovalgrind: package (e.g. libc6-dbg:i386).valgrind: valgrind: Cannot continue -- exiting now. Sorry.
-
很荣幸地能参与到华为鲲鹏众智计划项目中,本次参与的项目主要是实现在通用计算场景下的远程证明,包括对基础的主机完整性、可信容器完整性、以及PCIE设备系统镜像完整性的远程证明支持。在本次项目中,我从初期架构设计到中期模块开发再到后期测试以及文档编写等环节都完整地参与了进来,感受到了完整的开发流程,极大地提高了我的开发能力,受益匪浅。 在项目初期,先是由华为方面的老师介绍了项目的总体方案与实现分析,并根据服务器主场景把任务划分为story,给团队的每个成员分配大致的模块和具体的story作为首要任务,让我们很快的明确了自己要学习努力的方向。我负责的是远程证明客户端的开发,向上要和服务器端进行通信,处理服务器端传来的各种请求;向下要调用tpm进行各种操作来完成远程证明的流程。 在项目开发中,我学到了很多。首先是通过具体的开发实现,我对可信计算远程证明的相关内容理解的更深了,很多书上一笔带过的细小内容,要了自己要实现的时候都是非常重要的。比如在复现物理tpm的Endorsement Key时,其中有一个EKParams,我把TCG规范EK部分的文档翻了好多遍,问了老师很多问题,把里面每个字段的功能含义都了解之后才成功复现出来。其次,在这个项目的开发过程中我养好了良好的开发习惯。老师们不厌其烦地一次次评阅我们提交的代码,指出我们的问题并帮助我们改正。比如某些函数功能太多复杂,嵌套过深;某些注释写的不够简洁、易懂;某些错误的处理方式不好等。此外,每周的大小组会提高了我的团队交流合作能力,大的方向上需要逐步实现自己负责的模块,小的方向上需要和其他模块的负责人员沟通来帮助实现他们的模块,不断地交流让我对项目整体有了更深的认识。 最后,非常感谢华为鲲鹏众智平台给我们提供了项目实践的机会,让我们能实际参与一个优秀的大公司项目的完整开发流程。希望我以后能有更多机会参与到类似的项目中,学到更多的知识,也为华为的软件生态建设贡献自己的一份薄力。武汉大学 - 张立强研究团队 - 贾韵昊指导老师:张立强
-
非常有幸能够参加华为众智开源使能虚拟化软件适配1期项目,在本次项目中我得到了大幅的提示,对于一些虚拟化组件有了更加深刻的认识,在本次项目中,我负责对calico组件进行验证 在这个云的时代,Kubernetes是大家十分熟悉的一个开源项目,在k8s中网络组件是十分重要的,calico作为众多组件之一,calico有着易扩展,资源使用更少等特点。 下面是我的项目经验的分享docker Driver问题原因: 是由于docker的Cgroup Driver和kubelet的Cgroup Driver不一致导致的,此处选择修改docker的和kubelet一致问题查看: docker info | grep Cgroup Cgroup Driver: cgroupfs解决办法: 编辑文件/usr/lib/systemd/system/docker.service修改ExecStart=/usr/bin/dockerd --exec-opt native.cgroupdriver=systemdsystemctl daemon-reloadsystemctl restart dockerdocker info | grep CgroupCgroup Driver: systemd 十分荣幸能够加入到这个项目中,为国产生态系统奉献出自己的一份力量,通过本次项目,我对于k8s有了更深刻的了解,极大的提高了自己的能力。视同智能科技有限公司-华为鲲鹏众智项目团队-杨广业指导老师:徐志威
-
很荣幸参加鲲鹏众智的虚拟化适配1期项目,项目主要是在TaiShan200 2280服务器上验证虚拟化软件的兼容性,项目中我主要负责Qume安装以及基本功能验证确保对应版本的软件组件功能正常。 项目刚开始的时候,对于qemu这一个软件我并不是那么的熟悉,我对于qemu的认知停留qemu在是kvm虚拟机的一个组件,qemu是什么?qemu具体的作用是什么?这些我都不了解。我开始去官方网站和一些论坛上仔细了解Qemu,在项目初期的时候进行的不是那么顺利,因为网络上单独使用Qemu的数量并不是很多,有关Qemu的信息也不是特别多,只能够在官网上了解一下功能的实现,但是官方网站的示例都是x86的,只能根据官方示例而不断尝试。 下面是在项目实施过程中的一些经验分享编译安装 #在Arm上编译安装Qemu先安装edk2-aarch64.noarch#对于Arm系统运行Qemu需要运用QEMU_EFI.fd 进行启动#关于Qemu 的VNC登陆在编译安装之前需要安装gnutls-devel #Qemu VNC 的秘钥生成certtool --generate-privkey > ca-key.pem================================cat > ca.info <<EOFcn = Name of your organizationcacert_signing_key EOF================================certtool --generate-self-signed \ --load-privkey ca-key.pem \ --template ca.info \ --outfile ca-cert.pem================================cat > server.info <<EOForganization = Name of your organizationcn = hostNNN.foo.example.comdns_name = hostNNNdns_name = hostNNN.foo.example.comip_address = 10.0.1.87ip_address = 192.8.0.92ip_address = 2620:0:cafe::87ip_address = 2001:24::92tls_www_serverencryption_keysigning_keyEOF=================================certtool --generate-privkey > server-key.pem=================================certtool --generate-certificate \ --load-ca-certificate ca-cert.pem \ --load-ca-privkey ca-key.pem \ --load-privkey server-key.pem \ --template server.info \ --outfile server-cert.pem=================================cat > client.info <<EOFcountry = GBstate = Londonlocality = City Of Londonorganization = Name of your organizationcn = hostNNN.foo.example.comtls_www_clientencryption_keysigning_keyEOF=================================certtool --generate-privkey > client-key.pem=================================certtool --generate-certificate \ --load-ca-certificate ca-cert.pem \ --load-ca-privkey ca-key.pem \ --load-privkey client-key.pem \ --template client.info \ --outfile client-cert.pem=================================== 近些年来,国家计算机行业在飞速的发展,但是随着发展,国家之间的竞争也开始渐渐激烈,如今这种环境下,发展国产处理器以及arm生态系统是十分重要的,我十分荣幸能够加入到这个项目中,为本国生态系统贡献自己的一份力量。视同智能科技有限公司-华为鲲鹏众智项目团队-朱时锦指导老师:徐志威
-
本次迁移实践的目的,是将气象解决方案迁移到openEuler+鲲鹏的计算平台,充分发挥openEuler+鲲鹏在HPC场景的性能优势。项目中的软件主要由c/c++、Fortran语言编写。在移植过程中有源码编译,需要掌握编码语言,能分析并处理出现的源码问题。掌握clang和gcc编译相关知识,处理编译问题。还需掌握HPC相关技能,如MPI的应用。要求编译器为毕昇编译器,MPI为HyperMPI。移植过程中部分软件指定MPI编译源码;测试过程部分HPC软件需要进行多节点布置测试也依赖于MPI。要求HPC软件是源码安装。依赖包安装首选源码安装,其次yum安装。安装需要分析部署,考虑HPC软件依赖包的所需版本,达到有效兼容,合理匹配,实现优性能安装。由客户指定的算例得到测试结果。根据记录数据,分析制作性能对比图,直观了解软件移植的性能差异。软件测试的方式分为单节点和多节点方式,根据实际情况选择。最终实现CentOS和openEuler两个平台的测试性能对比,达到客户的要求。迁移目标:气象HPC组件运行在openEuler+Kunpeng平台。性能调优,保证HPC组件迁移至鲲鹏后的性能不低于X86平台的90%;主要工作:使用社区最新发布的毕昇编译器进行编译;MPI软件使用HyperMPI;使用IMB、IOR、Stream工具进行性能测试,并于CentOS平台性能对比。性能调优:OS调优:页大小设置:关闭透明大页内存THP,内存页64K。资源限制:ulimits取消解除硬资源和软资源的限制(CPU时间、最大线程数等)。IO优化:开启pageCache、预读,减少磁盘IO操作。基础软件调优:编译器设置:使用GCC最新版本,配置-march(针对鲲鹏优化)、-Ofast参数。MPI调优:配置MPI绑核、配置rank减少跨节点通信。线程核绑定:配置线程与核绑定HPC-WAN调优实现鲲鹏平台性能超过X86调优结果:气象HPC组件运行在openEuler+Kunpeng平台正常运行,整体性能超过通用平台,超过迁移性能目标。
-
本次迁移实践的目的,是将气象解决方案迁移到openEuler+鲲鹏的计算平台,充分发挥openEuler+鲲鹏在HPC场景的性能优势。项目中的软件主要由c/c++、Fortran语言编写。在移植过程中有源码编译,需要掌握编码语言,能分析并处理出现的源码问题。掌握clang和gcc编译相关知识,处理编译问题。还需掌握HPC相关技能,如MPI的应用。要求编译器为毕昇编译器,MPI为HyperMPI。移植过程中部分软件指定MPI编译源码;测试过程部分HPC软件需要进行多节点布置测试也依赖于MPI。要求HPC软件是源码安装。依赖包安装首选源码安装,其次yum安装。安装需要分析部署,考虑HPC软件依赖包的所需版本,达到有效兼容,合理匹配,实现优性能安装。由客户指定的算例得到测试结果。根据记录数据,分析制作性能对比图,直观了解软件移植的性能差异。软件测试的方式分为单节点和多节点方式,根据实际情况选择。最终实现CentOS和openEuler两个平台的测试性能对比,达到客户的要求。迁移目标:气象HPC组件运行在openEuler+Kunpeng平台。性能调优,保证HPC组件迁移至鲲鹏后的性能不低于X86平台的90%;主要工作:使用社区最新发布的毕昇编译器进行编译;MPI软件使用HyperMPI;使用IMB、IOR、Stream工具进行性能测试,并于CentOS平台性能对比。性能调优:OS调优:页大小设置:关闭透明大页内存THP,内存页64K。资源限制:ulimits取消解除硬资源和软资源的限制(CPU时间、最大线程数等)。IO优化:开启pageCache、预读,减少磁盘IO操作。基础软件调优:编译器设置:使用GCC最新版本,配置-march(针对鲲鹏优化)、-Ofast参数。MPI调优:配置MPI绑核、配置rank减少跨节点通信。线程核绑定:配置线程与核绑定HPC-WAN调优实现鲲鹏平台性能超过X86调优结果: 气象HPC组件运行在openEuler+Kunpeng平台正常运行,整体性能超过通用平台,超过迁移性能目标。
-
# 基于KML_SPBLAS的JAVA语言适配 ### 项目介绍 本项目的主要任务是为鲲鹏处理器的高性能稀疏线性代数库函数提供Java平台适配,包括向量与矩阵,矩阵与矩阵等共32个函数。基本原理是利用Java语言的JNI调用C语言的高性能库函数接口。 下面详细介绍我们团队在此次项目中的经验总结。 ### JNI简述 **JNI**是Java Native Interface的缩写,为Java程序提供与本地程序交互的能力。使用JNI技术,能够使得Java程序充分利用本地代码的优势,如高性能,不必重复造轮子等,在生产中,有着诸多实用价值。  ### JNI工作流程 JNI的典型使用场景是:Java程序调用C,C++代码编译而成的动态库文件。动态库文件在Windows下是.dll文件,在Linux下为.so文件。其主要工作流程如图所示:  1. 编写.java源代码,其中用native关键字标明需要本地实现的函数。 2. 使用命令 `javac -h 输出位置> 源代码路径>` 编译出.h头文件。 3. 编写.cpp源代码实现.h文件中声明的native函数。 4. 编译.h头文件和.cpp源文件生成.dll动态库,并移动到.java源代码中指定的位置。 5. 使用命令 `javac 源代码路径>` 将.java源代码编译成.class字节码。 6. 使用命令 `java 类名>` 执行类名.class文件,调用.dll库文件得到输出。 ### Hello, world! 这里实现一个简单的Windows版本的demo,带读者来熟悉上述流程。 1. 编写Hello.java源代码 ```java public class Hello { // native 关键字声明native函数 native void sayHelloToC(); // 加载 java2c.dll库文件 static { System.loadLibrary("java2c");} public static void main(String []args){ Hello hello = new Hello(); hello.sayHelloToC(); } } ``` 2. 在Hello.java所在目录,打开cmd命令行,编译出Hello.h头文件。(也一并编译出了Hello.class文件) ```sh javac -encoding utf-8 -h . Hello.java ``` utf-8防止中文注释乱码,. 表示输出到当前路径下。 3. 为了简化较长的.dll编译命令,此处我们借助 Dev-C++ 开发工具来完成C++代码的编写和编译。 1. 打开Dev-C++,新建dll项目,将自动生成dll.h和dllmain.cpp两个文件。 2. 将dll.h的内容替换为Hello.h。 ```c++ /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class Hello */ #ifndef _Included_Hello #define _Included_Hello #ifdef __cplusplus extern "C" { #endif /* * Class: Hello * Method: sayHelloToC * Signature: ()V */ JNIEXPORT void JNICALL Java_Hello_sayHelloToC (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif ``` 3. 清空dllmain.cpp中的内容,修改为如下 ```c++ #include"dll.h" #include // 实现dll.h中声明的函数 JNIEXPORT void JNICALL Java_Hello_sayHelloToC (JNIEnv * env, jobject obj){ printf("Hello, C! I am Java."); } ``` 4. 编译生成.dll库文件。 dll.h的第一行,引入了jni.h头文件。在java安装目录下的include文件夹,找到**jni.h**文件和**jni_md.h**。将它们复制到dev-c++项目的 工具->编译选项->目录->C++包含文件 中的任一目录下。  点击编译,生成hello_c++.dll文件(hello_c++为项目名),将其重命名为java2c.dll(与1中的java源代码保持一致),移动到Hello.java所在的文件夹。 5. 编译Hello.java生成Hello.class字节码,其实在第2步已经顺带完成。 ```sh javac -encoding utf-8 Hello.java ``` 6. 在Hello.class目录下,打开cmd命令行,执行字节码程序。 ```sh java Hello ```  以上实现一个简单的demo,完成Java程序调用C++编写的动态库的目标。通过JNI技术还可以实现Java程序和C/C++程序间的数据传递,下面将一一陈述。 ### 基本数据 | Java类型 | JNI类型 | 描述 | | :------- | :------- | :--------------- | | boolean | jboolean | unsigned 8 bits | | byte | jbyte | signed 8 bits | | char | jchar | unsigned 16 bits | | short | jshort | signed 16 bits | | int | jint | signed 32 bits | | long | jlong | signed 64 bits | | float | jfloat | 32 bits | | double | jdouble | 64 bits | | void | void | void | JNI的基本数据类型与Java类型的对照表如上,下面演示传递基本类型的数据。 Hello.java中添加: ```java native double average(int x, int y); ``` Hello.h中新增: ```c++ /* * Class: Hello * Method: average * Signature: (II)D */ JNIEXPORT jdouble JNICALL Java_Hello_average (JNIEnv *, jobject, jint, jint); ``` java编译程序自动添加了三行注释,Class表示类名,Method表示方法名,Signature是java的函数签名,告诉我们函数的参数类型和返回类型。参数是两个Interger,返回是Double。 函数体代码中,函数返回值为jdouble与java中的double对映,函数名为程序自动生成的**Java _类名 _方法名**形式,JNIEnv参数为jni环境,jobject为native函数所在的java对象,这两个是jni自带的。后面两个jint参数对应原本java方法的int参数。 在dllmain.cpp中实现average的逻辑: ```c++ JNIEXPORT jdouble JNICALL Java_Hello_average (JNIEnv * env, jobject obj, jint x, jint y){ return jdouble(x + y) / 2; } ``` 执行输出: ```java System.out.println(hello.average(1, 2)); // 1.5 ``` ### 字符串 JNI的字符串处理函数丰富全面,此处演示传递字符串的简单例子,并以此引出JNI处理复杂数据类型时的一般流程。更多API文件见参考链接的官方文档。 Hello.java中添加: ```java native String sendMessage(String msg); ``` Hello.h中生成: ```c++ /* * Class: Hello * Method: sendMessage * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Hello_sendMessage (JNIEnv *, jobject, jstring); ``` dllmain.cpp中实现: ```c++ JNIEXPORT jstring JNICALL Java_Hello_sendMessage (JNIEnv * env, jobject obj, jstring msg){ // 1.convert jstring to cstring const char* cMsg = env->GetStringUTFChars(msg, NULL); if(NULL == cMsg) return NULL; // 2.use cstring printf("Java: %s\n", cMsg); // 3.release resources env->ReleaseStringUTFChars(msg, cMsg); // 4.return const char* cMsg2 = "Good afternoon! Miss.Java."; return env->NewStringUTF(cMsg2); } ``` 注意:JNI中需要手动显式地释放资源,否则会造成内存泄漏。 执行输出: ```java String msg = "Good morning! Mr.C++."; System.out.println("C++: " + hello.sendMessage(msg)); // Java: Good morning! Mr.C++. // C++: Good afternoon! Miss.Java. ``` ### 对象 JNI同样可以传递对象,也就是说,JNI让C/C++代码能够访问Java类中的成员变量和方法。 从这里开始,我们使用Maven来管理我们的代码。 新建maven项目,其目录结构如下:  Hello.java的代码如下 ```java package org.example; public class Hello { static { System.loadLibrary("java2c"); } private int num = 2021; private void printNum(){ System.out.println("In Java, num is " + num); } // 演示访问成员变量和方法 native void jniMethod(); public static void main(String []args){ Hello hello = new Hello(); hello.jniMethod(); } } ``` 此处引入了java包,且Hello中导入了Color类,所以如果直接在Hello.java同级文件夹下调用**javac**命令,会报找不到符号的错误,应在所有源文件的根目录,即maven项目的java文件夹下,调用**javac**命令。这样编译器能将包名和路径对应起来。 进入src\main\java路径,运行: ```sh javac -encoding utf-8 -h . ./org/example/Hello.java ``` 如果源文件还引入了其他位置的包,如test文件夹下的源文件引入了main文件夹下的包,可使用`javac -cp 依赖路径>`告知java编译器依赖包的位置。更多javac选项,可使用`javac -help`自行查看。 Hello.h中生成: ```c++ /* * Class: org_example_Hello * Method: jniMethod * Signature: ()V */ JNIEXPORT void JNICALL Java_org_example_Hello_jniMethod (JNIEnv *, jobject); ``` dllmain.h中实现定义的函数: ```c++ JNIEXPORT void JNICALL Java_org_example_Hello_jniMethod (JNIEnv* env, jobject obj){ jclass cls = env->GetObjectClass(obj); // fieldID is certain for a class jfieldID numField = env->GetFieldID(cls, "num", "I"); // get number jint num = env->GetIntField(obj, numField); printf("In C++, num is %d\n", num); // change number env->SetIntField(obj, numField, 2035); // call method jmethodID printNumField = env->GetMethodID(cls, "printNum", "()V"); env->CallVoidMethod(obj, printNumField); return; } ``` 执行编译,在maven项目中编译执行的路径不再是源文件所在的路径。为简单起见,我们将生成的dll文件放到系统环境变量中,以便java虚拟机能够找到。执行输出得到: ```c++ public static void main(String []args){ Hello hello = new Hello(); hello.jniMethod(); } // In Java, num is 2035 // In C++, num is 2021 ``` 通过JNI,获取对象的成员变量或调用对象的主要过程如下: 1. `GetObjectClass`通过jobject获得jclass,或者`FindClass`通过类名直接获得jclass 2. 通过jclass获得jfieldID获得jmethodID。 3. 使用jfieldID获取成员变量的值或使用jmethodID调用对象的方法。 dllmain.cpp中的"I"、"()V"是java的签名字符串,可以在终端通过`javap`命令获取。 ### 数组 jni也可以传递基本类型的数组和对象数组,此处通过向量加法来演示此功能。 Hello.java中新增: ```java native void vectorAdd(int[] a, int[] b, int[] c); public static void main(String []args){ Hello hello = new Hello(); int []a = {1, 2, 3}; int []b = {4, 5, 6}; int []c = new int[3]; hello.vectorAdd(a, b, c); for(int i:c){ System.out.print(i + " "); } ``` `javac -h`重新编译后,Hello.h中生成: ```c++ /* * Class: org_example_Hello * Method: vectorAdd * Signature: ([I[I[I)V */ JNIEXPORT void JNICALL Java_org_example_Hello_vectorAdd (JNIEnv *, jobject, jintArray, jintArray, jintArray); ``` 在dllmain.h中实现上述函数: ```c++ JNIEXPORT void JNICALL Java_org_example_Hello_vectorAdd (JNIEnv *env, jobject obj, jintArray a, jintArray b, jintArray c){ // 1.convert JNI jintArray to C jint[] jint *cA = env->GetIntArrayElements(a, NULL); jint *cB = env->GetIntArrayElements(b, NULL); jint *cC = env->GetIntArrayElements(c, NULL); jint len = env->GetArrayLength(a); // 2.use array for(jint i=0; i+ cB[i]; } // 3.release resources env->ReleaseIntArrayElements(a, cA, JNI_ABORT); env->ReleaseIntArrayElements(b, cB, JNI_ABORT); env->ReleaseIntArrayElements(c, cC, 0); return; } ``` 函数依旧分为:转化数据、使用数据、释放资源三步。 Release函数第三个参数为mode,有三个备选值如下: | mode | 行为 | | :--------- | :-------------------------------------------------------- | | 0 | copy back the content and free the elems buffer | | JNI_COMMIT | copy back the content but do not free the elems buffer | | JNI_ABORT | free the buffer without copying back the possible changes | 编译后执行得输出如下: ``` 5 7 9 ``` 对象数组与基本类型数组的方法相似,但是没有**Get``ArrayElements**对数组元素进行批量转化,究其原因,Java对象不能直接转化为C/C++的对象。 使用如下两个函数,可以操作基本数据类型数组的直接指针,极大的加快程序运行的效率。但同时,我们要保证在调用ReleasePrimitiveArrayCritical函数之前,不能进行任何可能导致线程阻塞的操作。 void * **GetPrimitiveArrayCritical**(JNIEnv *env, jarray array, jboolean *isCopy); void **ReleasePrimitiveArrayCritical**(JNIEnv *env, jarray array, void *carray, jint mode); ### 工程经验 #### c语言宏定义 观察`javac -h`生成的函数声明,我们会发现都是如下结构: ``` Java_包名_方法名 JNIEXPORT void JNICALL Java_org_example_Hello_jniMethod(...) JNIEXPORT void JNICALL Java_org_example_Hello_vectorAdd(...) ``` 当程序越来越复杂,我们调整Java的包结构,每一个地方都要修改。可以使用C++的宏替换来减少这种冗余如下: ```c++ #define FULL_FUNC_NAME(SHORT_NAME) Java_org_example_Hello_##SHORT_NAME JNIEXPORT void JNICALL FULL_FUNC_NAME(jniMethod)(...) JNIEXPORT void JNICALL FULL_FUNC_NAME(vectorAdd)(...) ``` #### 将dll动态库打入jar包 首先我们要明白Java加载动态库的方式: 1. **System.load** System.load加载绝对路径下的库文件,如: ```java System.load("D:\\workplace\\java2c.dll"); ``` 2. **System.loadLibrary** System.loadLibrary加载相对路径下的库文件,参数为库文件名,不包含库文件的扩展名,如: ```java System.loadLibrary("java2c"); ``` 这里java2c.dll必须在**java.library.path**这一jvm变量指向的路径中。 可以通过如下方法来获得该变量的值: ```java System.getProperty("java.library.path"); ``` 默认情况下,在Windows平台下,该值包含如下位置: 1)和jre相关的一些目录 2)程序当前目录 3)Windows目录 4)系统目录(system32) 5)系统环境变量path指定目录 上述两个函数都是以路径作为参数的,但是jar包中的文件没有路径,只能以文件流的形式获取。为了能将动态库文件打入jar包,并且能够顺利调用,我们的策略是将jar包中的动态库写入系统临时目录下,再调用System.load载入,参考代码如下: ```java static { // copy .so from jar to syetem tmp dir String libName = "java2c.dll"; String nativeTempDir = System.getProperty("java.io.tmpdir"); File extractedLibFile = new File(nativeTempDir + File.separator + libName); InputStream in = null; BufferedInputStream reader = null; FileOutputStream writer = null; if(!extractedLibFile.exists()){ try{ in = Level2.class.getClassLoader().getResourceAsStream(libName); reader = new BufferedInputStream(in); writer = new FileOutputStream(extractedLibFile); byte[] buffer = new byte[1024]; while(reader.read(buffer) > 0){ writer.write(buffer); } }catch(IOException e){ e.printStackTrace(); }finally { if (in != null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null){ try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } System.load(extractedLibFile.toString()); } ``` ### 参考链接 [JNIdemo图文](https://blog.csdn.net/WeiHao0240/article/details/99568579) [JNI完全指南文档](https://www.zybuluo.com/cxm-2016/note/563686) [JNI 官方文档](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html)
-
很荣幸参加《鲲鹏Java性能分析工具IntelliJ插件实现》项目开发工作的,我们项目主要是做Inellij插件开发实现性能分析工具功能。由于插件开发的特殊性,常常需要和一些命令行打交道,下面记录一次通过Java代码打开Windows证书安装窗口安装证书cer文件。思路如下:第一步:下载证书,保存到本地 通过cer文件下载接口将文件保存到本地,记录文件的保存位置第二步:通过代码在IDEA的Terminal命令窗口输入命令打开证书安装窗口 // 将项目对象,ToolWindow的id传入,获取控件对象 ToolWindow toolWindow = ToolWindowManager.getInstance(e.getProject()).getToolWindow("Terminal"); if (toolWindow != null) { // 无论当前状态为关闭/打开,进行强制打开ToolWindow toolWindow.show(new Runnable() { @Override public void run() { Process p = Runtime.getRuntime().exec("rundll32.exe cryptext.dll,CryptExtAddCER "+ path); } }); } }第三步:提醒用户重启IDEA,使证书生效 Messages.showMessageDialog("安装证书", "安装证书后请重启IDEA,证书才能生效", Messages.getInformationIcon());
-
IDEA是目前Java开发人员最受欢迎的工具开发之一,很重要的原因是其提供了很多插件,这让开发人员降低了开发难度,能更有效更高质量的开发代码,我也很荣幸成为IDEA插件开发的一员。 我所在的是鲲鹏Java性能分析工具IntelliJ这个开源项目,刚开始参与进来的时候感觉这个项目很难,因为对Java Swing这块的技术了解的很少。长时间下来感觉挺有意思的,以下我是我对Swing这块的总结: Swing图形组件是java中一套图形界面类,主要分为两类:容器类和元素类。容器类表示可以放置其他的元素组件或者容器组件,JFrame 窗体组件,JPanel 面板容器,JMeauBar 菜单栏;元素类表示不可以放其他的组件,比如:JButton 按钮组件,JLable 文本标签组件,JTextField 文本输入框组件,JPasswordField 密码输入框组件,JCheckBox 复选框组件等。主要就是在合理布局下各种组件之间的搭配,其中还有很多重要的事件,如:ActionEvents,ChangeEvents,ItemEvents等,来响应用户的鼠标点击等行为。 每当感觉自己已经掌握了Swing这门技术的时候,但是在开发过程中处处有惊喜,总会碰到这样或那样的难题,因此还是得通过不断的学习来提高自己,这样才能更好、更有效更轻松的为这个团队服务。加油!
上滑加载中