用Go汇编实现一个快速排序算法

本代码全网首发,使用Go plan9 windows arm64汇编,实现基础版快速排序算法。

未引入随机因子的快速排序的普通Go代码长这样。

func QuickSort(arr []int) {
	if len(arr) <= 1 {
		return
	}

	base, l, r := arr[0], 0, len(arr)-1
	for i := 1; i <= r; {
		if arr[i] > base {
			arr[i], arr[r] = arr[r], arr[i]
			r--
			continue
		}
		arr[i], arr[l] = arr[l], arr[i]

		l, i = l+1, i+1
	}

	QuickSort(arr[:l])
	QuickSort(arr[l+1:])
}

在这里插入图片描述

如下,使用windows arm64 Go plan9汇编实现的快速排序。

file: quickSort.s

#include "textflag.h"
// func QuickSortByASM(slice []int)
TEXT ·QuickSortByASM(SB), $104-24
   // NO_LOCAL_POINTERS
    MOVD R0 , tmp-8*3(SP);  MOVD R1 , tmp-8*4(SP)
    MOVD R2 , tmp-8*5(SP);  MOVD R3 , tmp-8*6(SP)
    MOVD R4 , tmp-8*7(SP);  MOVD R5 , tmp-8*8(SP)
    MOVD R6 , tmp-8*9(SP);  MOVD R7 , tmp-8*10(SP)
    MOVD R8 , tmp-8*11(SP); MOVD R9 , tmp-8*12(SP)
    MOVD R10, tmp-8*13(SP)

    MOVD slice+0(FP), R0    // arrayPtr
    MOVD slice+8(FP), R1    // arrayLength
    MOVD $0, R2             // l_index
    MOVD R1, R3             // r_index = arrayLength
    SUB  $1, R3             // r_index -= 1
    MOVD $0, R4             // pointer1
    MOVD $0, R5             // pointer2
    MOVD $8, R6             // dataSize
    MOVD $1,   R7           // index
    MOVD (R0), R8           // base   TODO random index
    MOVD $0,   R9

    CMP $1, R1; BLE LABEL_END       // if arrayLength <= 1 return
LABEL_FOR_START:
    CMP R3, R7; BGT LABEL_FOR_END   // if index > r_index return
    MOVD R7, R4      // offset = index
    MUL  R6, R4      // offset *= dataSize
    ADD R0,  R4      // arr[i] = R4
    MOVD (R4), R5    // arr[i]

    CMP R8, R5; BLE LABEL_SWAP // if arr[i] <= base

    MOVD R3, R5      // offset = r_index
    MUL  R6, R5      // offset *= dataSize
    ADD  R0, R5      // arr[r]

    MOVD (R5), R9    // tmp     = arr[r]
    MOVD (R4), R10   // tmp1    = arr[i]
    MOVD R10, (R5)   // arr[r]  = arr[i]
    MOVD R9, (R4)    // arr[i]  = tmp

    SUB  $1, R3       // r_index -= 1
    JMP LABEL_FOR_START
LABEL_SWAP:
    MOVD R7, R4
    MUL  R6, R4
    ADD  R0, R4
    MOVD R2, R5
    MUL  R6, R5
    ADD  R0, R5

    MOVD (R4), R9  // tmp = arr[i]
    MOVD (R5), R10 // tmp1 = arr[l]
    MOVD R10, (R4) // arr[i] = tmp1
    MOVD R9, (R5)  // arr[l] = tmp

    ADD $1, R2     // l_index += 1
    ADD $1, R7     // index += 1
    JMP LABEL_FOR_START
LABEL_FOR_END:
    MOVD R0, R4
    MOVD R2, R5
    MOVD R4, tmp-104(SP)
    MOVD R5, tmp-96(SP)
    CALL ·QuickSortByASM(SB)

    MOVD R2, R4
    ADD  $1, R4
    MUL  R6, R4
    ADD  R0, R4  // right address

    MOVD R1, R5  // tmp = arrayLength
    SUB  R2, R5  // tmp -= l_index
    SUB $1,  R5

    MOVD R4, tmp-104(SP)
    MOVD R5, tmp-96(SP)
    CALL ·QuickSortByASM(SB)
LABEL_END:
    MOVD  tmp-8*3(SP),  R0; MOVD  tmp-8*4(SP),  R1
    MOVD  tmp-8*5(SP),  R2; MOVD  tmp-8*6(SP),  R3
    MOVD  tmp-8*7(SP),  R4; MOVD  tmp-8*8(SP),  R5
    MOVD  tmp-8*9(SP),  R6; MOVD  tmp-8*10(SP), R7
    MOVD  tmp-8*11(SP),  R8;MOVD  tmp-8*12(SP), R9
    MOVD  tmp-8*13(SP), R10
    RET

该汇编版本快排基于普通版快排手写而成, 未加入stackmap信息,大数据量样本可能会出现panic,仅供参考。

对数器

package main

import (
	"fmt"
	"math/rand"
	"sort"
)

func QuickSortByASM(slice []int) // 汇编函数声明

func main() {
	N := 50
	for index := 0; index < 1000; index++ {
		slice := make([]int, N)
		for i := 0; i < N; i++ {
			slice[i] = rand.Int()
		}

		slice1 := make([]int, N)
		slice2 := make([]int, N)
		for i, v := range slice {
			slice1[i] = v
			slice2[i] = v
		}
		
		sort.Ints(slice1)
		QuickSortByASM(slice2)

		for i := 0; i < N; i++ {
			if slice1[i] != slice2[i] {
				fmt.Println(slice)
				fmt.Println(slice1)
				fmt.Println(slice2)
				panic(i)
			}
		}
	}
	fmt.Println("pass")
}

pass

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

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

相关文章

选择卓越的数据防泄密软件,关键评判标准揭秘!

如今数据安全环境不断遭受挑战&#xff0c;面对复杂、未知的数据泄露手段&#xff0c;使用数据防泄密软件成为当前企事业单位的最佳选择&#xff0c;而一款好的数据防泄密软件有哪些主要标准&#xff1f;迅软DSE带大家从以下几点判断。 1.稳定性&#xff1a;稳定性是产品选型最…

yml中“@project.description@“失效

pom文件中添加如下代码 <resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource> </resources> 效果如下&#xff1a; 原理&#xff1a; yml文件中类似 ${spring.applica…

SpringSecurity安全授权

目录 前言 正文 1.基本流程 2.基本用法 3.配置项 4.HttpSecurity 方式和内存认证方式 5.认证流程 6.基于数据库查询的登录验证 7.多种角色权限认证 8.自定义权限认证 总结 前言 安全对于任何系统来说都是非常重要的&#xff0c;权限的分配和管理一直都是开发者需…

ROS2 学习08 导航Nav2:简介、安装、测试效果、错误处理

1、简介 在ROS2中自动导航使用Nav2来实现。 Nav2 使用几个独立的模块化服务&#xff0c;通过 ROS 2接口&#xff08;例如动作服务器或服务&#xff09;与行为树 (BT) 通信。 Nav2 输入包括&#xff1a;TF转换、一个地图源、一个行为树 (BT) XML 文件和相关的传感器数据源; Nav…

基于javaweb教务管理系统

一、系统架构 前端&#xff1a;jsp | jquery | layui 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | maven | mysql 二、代码及数据库 三、功能介绍 01. 登录页 02. 主页 03. 系统管理-用户管理 04. 系统管理-角色管理 05. 系统管理-权限管…

《PySpark大数据分析实战》-08.宽窄依赖和阶段划分

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

express 下搞一个 websocket 长连接

安装模块 npm i express npm i express-ws 新建文件app.js 先安排源码 监听端口 7777 var express require(express) var app express() require(express-ws)(app)var port 7777 var clientObject {} app.ws(/, (client, req) > {// 连接var key req.socket.re…

运筹学经典问题(七):旅行商问题(TSP)

问题描述 给定一系列城市和每对城市之间的距离&#xff0c;求解访问每座城市一次并回到起始城市的最短回路。 数学建模 集合&#xff1a; V V V&#xff1a;城市集合 常量&#xff1a; c i j c_{ij} cij​&#xff1a;城市 i i i到城市 j j j之间距离, i ≠ j i \neq j i…

基于C++的简单BP神经网络(C++)

需求&#xff1a;在某些无网络的实验机器上&#xff0c;由于某些任务需求&#xff0c;需要拟合特定的函数&#xff0c;因此需要部署基于C开发的神经网络&#xff0c;本文在不使用外部库的情况下&#xff0c;编写简单的神经网络&#xff0c;实现简单函数的拟合。 一、简介 本文…

我常用的几个经典Python模块

Python常用的模块非常多&#xff0c;主要分为内置模块和第三方模块两大类&#xff0c;且不同模块应用场景不同又可以分为文本类、数据结构类、数学运算类、文件系统类、爬虫类、网络通讯类等多个类型。 大家常用的内置模块比如&#xff1a;math、re、datetime、urllib、os、ra…

CountDownLatch用法、详解

目录 ​编辑 概述&#xff1a; 应用场景&#xff1a; 优点&#xff1a; 缺点&#xff1a; 主要方法&#xff1a; 1. CountDownLatch(int count)&#xff1a; 2. void await()&#xff1a; 3. boolean await(long timeout, TimeUnit unit)&#xff1a; 4. void countDo…

【Python】计算一年内的总天数(还有跨年日期)

花了一段时间才找到Python中求一年中总日数&#xff08;total day of the Year&#xff09;的格式代码&#xff0c;所以也把计算方法记录下来。 基本 首先&#xff0c;简单地找出一年中的总天数&#xff0c; strftime() 和 strptime() 的格式代码是 %j ↓看这里 使用 strft…

基于当前实时云渲染的特点,用户体验主要受哪些因素影响?

在回答这个问题之前我们首先需要理解什么是实时云渲染&#xff1f; 点量实时云渲染是一种基于云计算低延迟传输&#xff0c;实现各种轻终端便捷使用云端大型软件和3D应用的一种云技术解决方案。这一技术解决方案通过将应用程序或内容置于云端服务器上运行&#xff0c;然后以视…

测试用例设计方法六脉神剑——第四剑:石破天惊,功能图法攻阵

1 引言 前面几篇文章为我们讲述了因果图、判定表、正交试验等几种方法&#xff0c;主要是针对于不同条件输入输出的组合进行测试&#xff0c;但在实际需求中&#xff0c;我们也常会遇到需要对被测对象的状态流转进行验证的情况&#xff0c;此时前面几种方法将不再适用&#xf…

测试用例设计方法:功能图

1 引言 前面几篇文章为我们讲述了因果图、判定表、正交试验等几种方法&#xff0c;主要是针对于不同条件输入输出的组合进行测试&#xff0c;但在实际需求中&#xff0c;我们也常会遇到需要对被测对象的状态流转进行验证的情况&#xff0c;此时前面几种方法将不再适用&#xf…

OpenHarmony 鸿蒙系统之开发环境安装

一、首先在下方链接网址中下载DevEco Studio的安装包。 DevEco Studio历史版本下载-HarmonyOS应用开发官网

Linux CentOS7 Docker安装Jenkins

1 sudo yum update #确保yum包更新到最新 service network restart #重启网络 2、查询镜像 docker search jenkins 3、拉取镜像 docker pull jenkins/jenkins #拉取镜像 4、创建Jenkins工作目录&#xff0c;并将容器内目录挂载到此目录…

23.12.10日总结

周总结 这周三的晚自习&#xff0c;学姐讲了一下git的合作开发&#xff0c;还有懒加载&#xff0c;防抖&#xff0c;节流 答辩的时候问了几个问题&#xff1a; 为什么在js中0.10.2!0.3? 在js中进行属性运算时&#xff0c;会出现0.10.20.300000000000000004js遵循IEEE754标…

CSS伪元素的特殊机制

概念 伪元素是CSS中的一种特殊机制&#xff0c;用于在元素的特定位置插入虚拟的内容。它们不是实际存在于HTML文档中的元素&#xff0c;而是通过CSS样式来创建和控制的。 伪元素使用双冒号&#xff08;::&#xff09;作为标识符&#xff0c;用于区分伪类选择器&#xff08;使…

Linux Shell——基本语法(变量、流程控制)

shell基本语法 一、变量二、流程控制 总结 最近学习了shell脚本&#xff0c;记录一下相关语法 一、变量 变量是很重要的&#xff0c;是用于存储数据值的容器 变量名要遵循以下规则&#xff1a; &#xff08;1&#xff09;只能包含字母、数字和下划线 &#xff08;2&#xff09…