【代码分享】使用 avx2 + 查表法,优化凯撒加密
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
接上一篇:【代码分享】使用 avx512 + 查表法,优化凯撒加密
好不容易捣鼓出来了 avx512 指令集的查表法代码,可是部署的时候发现服务器不支持 avx512 指令集。
终于,avx2 版本的查表法终于写出来了。上代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <immintrin.h>
#include <avx2intrin.h>
#include <inttypes.h>
#include <assert.h>
typedef uint32_t Table[26][256];
void initTable(Table *table){
for (int i=0; i<26; i++){
for (int j=0; j<256; j++){
if (j>='a' && j<='z'){
(*table)[i][j] = (uint8_t)((j-'a'+i)%26 + 'a');
} else if (j>='A' && j<='Z'){
(*table)[i][j] = (uint8_t)((j-'A'+i)%26 + 'A');
} else {
(*table)[i][j] = j;
}
}
}
}
void caesarEncodeAVX2(void* out1, void* in1, uint64_t len, uint64_t rot, void* table1){
uint8_t* out = (uint8_t*)out1;
uint8_t* in = (uint8_t*)in1;
Table* table = (Table*)table1; // 这些代码为了解决 cgo 中函数调用的警告
//
rot = rot % 26;
uint32_t* line = (uint32_t*)((*table)[rot]);
#define batchSize 16
uint64_t tailLen = len & 0x0f;
uint8_t* end = in + len - tailLen;
uint8_t* start = in;
const __m256i index_mask = _mm256_set_epi32(
7, 6, 3, 2,
5,4, 1, 0
);
for (; start<end; out += batchSize, start += batchSize){
__m128i src = _mm_loadu_si128(start); // 加载 16 个字符,但只处理前面 8 个字符
__m256i srcI32 = _mm256_cvtepu8_epi32(src); // 前 8 个字节,转换为 32 字节
__m256i foundHead = _mm256_i32gather_epi32(line, srcI32, 4); // 8 字节查表
// 处理后面 8 字节
src = _mm_srli_si128(src, 8); // 移动 8 字节,也就是 64 位
srcI32 = _mm256_cvtepu8_epi32(src); // 后 8 个字节,转换为 32 字节
__m256i foundTail = _mm256_i32gather_epi32(line, srcI32, 4); // 8 字节查表
// 进行压缩
__m256i found16 = _mm256_packus_epi32(foundHead, foundTail); // 16 个 16 位的值
/*
_mm256_packus_epi32 这个指令非常的恶心:aaaa bbbb 合并成了 aa bb aa bb
于是还要用下面这个指令把顺序换过来
*/
found16 = _mm256_permutevar8x32_epi32 (found16, index_mask); // 换过来了,正常了
found16 = _mm256_packus_epi16(found16, _mm256_setzero_si256());
found16 = _mm256_permutevar8x32_epi32 (found16, index_mask); // 换过来了,正常了
//存储
__m128i result = _mm256_castsi256_si128(found16);
_mm_storeu_si128 (out, result);
}
//
end = in + len;
for (; start<end; start++, out++){
*out = (uint8_t)line[*start];
}
}
// 逐字节处理的版本
void caesarEncode(uint8_t* out, uint8_t* in, int len, int rot, Table* t){
rot = rot % 26;
uint8_t* end = in + len;
uint32_t* line = (uint32_t*)((*t)[rot]);
for (;in<end; in++, out++){
*out = (uint8_t)line[*in];
}
}
编译:
gcc -o caesar caesar.c -g -w -mavx -mavx2 -O3
测试了一下各个版本的性能表现:
逐字节处理版本:total:201429 us, avg: 100.715 ns/op
AVX2 版本: total:51059 us, avg: 25.529 ns/op
AVX512 版本: total:49756 us, avg: 24.878 ns/op
avx512 版本只比 avx2 快了一点点,鸡肋!
【代码分享】使用 avx2 + 查表法,优化凯撒加密的更多相关文章
- 经典算法,yuv与rgb互转,查表法,让你的软件飞起来
代码的运算速度取决于以下几个方面 1. 算法本身的复杂度,比如MPEG比JPEG复杂,JPEG比BMP图片的编码复杂. 2. CPU自身的速度和设计架构 3. CPU的总线带宽 4. 您自己代码的写法 ...
- YUV420查表法高效、无失真的转换为RGB32格式
YUV格式有两大类:planar和packed.planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V,这里所讲述的就是这中存储格式的:packed的YUV ...
- C#,Java,C -循环冗余检验:CRC-16-CCITT查表法
C#代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...
- 查表法计算CRC16校验值
CRC16是单片机程序中常用的一种校验算法.依据所采用多项式的不同,得到的结果也不相同.常用的多项式有CRC-16/IBM和CRC-16/CCITT等.本文代码采用的多项式为CRC-16/IBM: X ...
- 【C语言学习笔记】空间换时间,查表法的经典例子!知识就是这么学到的~
我们怎么衡量一个函数/代码块/算法的优劣呢?这需要从多个角度看待.本篇笔记我们先不考虑代码可读性.规范性.可移植性那些角度. 在我们嵌入式中,我们需要根据实际资源的情况来设计我们的代码.比如当我们能用 ...
- C语言:十进制进制转换为其他进制(思想:查表法)
// // main.c // Hex conversion // // Created by ma c on 15/7/22. // Copyright (c) 2015年 bjsxt. A ...
- 最简单的CRC32源码-查表法
这个算法是在逐BYTE法的基础上进行修改的,在上一篇文章里我们说过,如果不查表的话,逐BYTE法和逐BIT法没什么区别,现在我们就把这个算法写出来,注意在调用CRC校验函数前需要先调用表生成函数: u ...
- 嵌入式C语言查表法的项目应用
嵌入式C实战项目开发技巧:如果对一个有规律的数组表进行位移操作 就像下面的这个表 之前写过上面这个标题的一篇文章,讲的是以位移的方式去遍历表中的数据,效率非常高,但是,如果要实现一个乱序的流水灯或者跑 ...
- 嵌入式C语言查表法
转自:https://blog.csdn.net/morixinguan/article/details/51799668 作者:Engineer-Bruce_Yang 就像下面的这个表 之前写 ...
- RGB2GRAY 各种算法速度比较,整形乘法比查表法快!
1. 查表法,外循环用 这种格式 : //for(int j = 0; j != h; ++j)// for(int i = 0; i!=w;++i)//. for(int j = 0; j != ...
随机推荐
- 手把手带你玩转LiteOS Ping组件
摘要:本期小编为大家带来LiteOS开源版本Ping组件的使用说明,请跟随小编的步伐一起进入探索之旅吧! 本文分享自华为云社区<LiteOS组件尝鲜-玩转Ping>,作者:Lionlace ...
- 敏捷开发专家一席谈:云原生技术下的华为云DevOps实践之路
摘要:听华为云DevCloud首席技术布道师徐毅讲述云原生下的DevOps实践. 本文分享自华为云社区<敏捷开发专家一席谈:云原生技术下的华为云DevOps实践之路>,作者:华为云社区精选 ...
- 性能持续突破!火山引擎ByteHouse上线向量检索能力
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力"异军突 ...
- 挖掘优质短视频超百万条,火山引擎DataLeap助力电商平台生态治理
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在人们的日常生活中,网购已经成为人们生活中不可或缺的购物形式. 根据<中国社交电商行业发展白皮书( ...
- 多领域应用落地,火山引擎ByteHouse加速云数仓升级
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近日,火山引擎数智平台VeDI直播活动「超话数据」在线举办,来自火山引擎的产品及解决方案专家分享了以ByteH ...
- 【Qt Libraries】QUrl 的基本使用方法
参考博客: https://www.cnblogs.com/liushui-sky/p/10892097.html https://www.cnblogs.com/ShineLeBlog/p/1495 ...
- AtCoder Educational DP Contest 刷题记录
写在前面 深感自己 DP 很弱的 村人B 刷了点 DP 题,题集地址戳这里. 后记:刷完后感觉自己又行了 A - Frog 1 题意 给定 \(n\) 个石头,第 i 个石头的高度为 \(h_i\). ...
- AtCoder Beginner Contest 208 A~E个人题解
比赛链接:Here A - Rolling Dice 水题 一个六面的骰子,请问摇动 \(A\) 次最后的点数和能否为 \(B\) 如果 \(B \in [a,6a]\) 输出 YES C++ voi ...
- vivo 全球商城:订单中心架构设计与实践
一.背景 随着用户量级的快速增长,vivo 官方商城 v1.0 的单体架构逐渐暴露出弊端:模块愈发臃肿.开发效率低下.性能出现瓶颈.系统维护困难. 从2017年开始启动的 v2.0 架构升级,基于业务 ...
- SpringBoot Serverless 实战 | 监控调试
SpringBoot 是基于 Java Spring 框架的套件,它预装了 Spring 的一系列组件,让开发者只需要很少的配置就可以创建独立运行的应用程序.在云原生的世界,有大量的平台可以运行 Sp ...