【代码分享】使用 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 != ...
随机推荐
- vue2升级vue3:webpack vue-loader 打包配置
如果没有啥特别的需求还是推荐vue-cli! vite vue3 TSX项目 虽然vite 很香,但是vite rollup 动态加载,多页面 等问题比较难搞 vite的缺点 wepback _ ...
- 使用 cron4j-solon-plugin 开发定时任务(新)
(一)新建一个 maven 空项目 (二)添加 maven 引用 <dependency> <groupId>org.noear</groupId> <art ...
- C# Winform 自定义窗口,最大化遮住任务栏
解决 C# Winform 自定义窗口,最大化遮住任务栏 的问题,可以通过获取屏幕大小来控制最大值,来实现,代码如下 Rectangle ScreenArea = System.Windows.For ...
- Django rest_framework用户认证和权限
完整的代码 https://gitee.com/mom925/django-system 使用jwt实现用户认证 pip install djangorestframework-simplejwt 重 ...
- GOS会计凭证上传附件
1.GOS介绍 GOS是一个连接文档和SAP内各种对象的工具,在SAP的一些凭证中,可以通过GOS进行附件的上传.查看和删除等功能,例如采购订单.会计凭证等. 如果没有这个按钮,可以将当前登录用户的类 ...
- 神经网络优化篇:详解RMSprop
RMSprop 知道了动量(Momentum)可以加快梯度下降,还有一个叫做RMSprop的算法,全称是root mean square prop算法,它也可以加速梯度下降,来看看它是如何运作的. 回 ...
- Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题)
补题链接:Here 1535A. Fair Playoff 四名选手参加了季后赛.比赛按以下方案进行:第一名选手与第二名选手比赛,第三名选手与第四名选手比赛,然后两人中的获胜者进入决赛. 众所周知,在 ...
- 2019年第十届蓝桥杯国赛C++B组
部分题目示意图来自网络,所以会带水印 最后编辑时间: 2021年5月12日 统一声明 如果不写默认带有常用头文件 如果不表明主函数默认表示在 void solve(){} 默认使用 using nam ...
- @Constraint注解,做特殊的入参校验
// @Constraint 是 Java 中的注解之一,用于标记自定义的约束注解.约束注解通常用于数据验证,用来限制字段的取值或格式,确保数据的合法性. @Constraint(validatedB ...
- element-china-area-data
https://blog.csdn.net/xiejnpeng/article/details/111400199
