搜索
bottom↓
回复: 22

一维数组,1bit 1bit的左移,有啥优化方式?空间换时间?

[复制链接]

出0入4汤圆

发表于 2019-12-23 11:38:17 | 显示全部楼层 |阅读模式
本帖最后由 fbwcpu 于 2019-12-23 19:06 编辑

用在LED点阵上的数组移位,向左滚动显示数据。

一维数组,全部左移1bit,有啥优化方式?  有个网友说有空间换时间方式,用查表法,不知怎么实现的,有朋友知道吗?
我就是用的最笨的办法,一个字节左移一个bit ,最右边空出的1bit再末尾填充下一字节的bit7 这样的周而复始。  就是不知道这空间换时间怎么弄的,我flash容量是足够大的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981

出0入0汤圆

发表于 2019-12-23 11:41:05 | 显示全部楼层
将bit数据变成char数据。利用指针来实现左移?

出0入59汤圆

发表于 2019-12-23 11:42:53 | 显示全部楼层
把缓存区 按 32位的变量 方式去移位, 效率至X200%

出0入17汤圆

发表于 2019-12-23 11:56:10 | 显示全部楼层
本帖最后由 think_a_second 于 2019-12-23 11:59 编辑

1. STM32有位带Bit Band的,
2. 豪一点的话,用FPGA
3. 通用的做法,是搞清需求,不移位,将所有数据看作一串,用脚标word_index指示当前到哪个字(或字节),再用bit_index指示当前到哪个位

出0入0汤圆

发表于 2019-12-23 11:57:43 | 显示全部楼层
我有个不成熟的想法,就是利用SPI和DMA,来达到移位的效果,只是要考虑一下怎么让数据错一个位。

出0入4汤圆

发表于 2019-12-23 12:00:38 | 显示全部楼层
本帖最后由 banyai 于 2019-12-23 12:08 编辑

足够大有多大?最快的方法应该是做一个Table[256][256]的数组,然后数组m[n] = Table[m[n]][m[n-1]],就可以了,最后一个循环m[n-1]选0或0x80,没那么大就用Table[256][2],m[n] = Table[m[n]][(m[n-1]&0x80)==0?0:1]……

出0入55汤圆

发表于 2019-12-23 12:03:03 来自手机 | 显示全部楼层
直接搞成环形,用读写指针不是更好?不用移位

出0入4汤圆

 楼主| 发表于 2019-12-23 12:45:31 | 显示全部楼层
jssd 发表于 2019-12-23 12:03
直接搞成环形,用读写指针不是更好?不用移位

指针不能指向一个bit位吧  此方法肯定不行。

出0入4汤圆

 楼主| 发表于 2019-12-23 12:46:18 | 显示全部楼层
lcw_swust 发表于 2019-12-23 11:57
我有个不成熟的想法,就是利用SPI和DMA,来达到移位的效果,只是要考虑一下怎么让数据错一个位。 ...

不能操作bit位吧

出0入0汤圆

发表于 2019-12-23 13:05:21 | 显示全部楼层
本帖最后由 lcw_swust 于 2019-12-23 13:08 编辑
fbwcpu 发表于 2019-12-23 12:46
不能操作bit位吧


举个例子,SPI1与SPI2互联,我能否用GPIO方式操作SPI1的SCK、MOSI输出1位数据,然后再将IO配置为SPI功能,输出一组数据,
这样,SPI2收到的数据就全都移了一个位。

出0入0汤圆

发表于 2019-12-23 13:46:21 | 显示全部楼层
持续关注,一维数组是多大?
union
{
    unsigned char array[8];
    unsigned long long  b;
}abc={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

int main(int argc, char *argv[])
{

    abc.b<<=1;
    for(int i=0;i<8;i++)
     qDebug("%02x",abc.array[i]);

}


超过这个还有办法

出0入0汤圆

发表于 2019-12-23 13:56:04 | 显示全部楼层
是不是一定要移位呢? 可不可以从读取数据着手,或者写入的时候。 写入的时候能不能先计算好在写入,或者读取的时候计算一下

出0入0汤圆

发表于 2019-12-23 14:56:28 | 显示全部楼层
看你这个问题都发了好几个帖子了,有这么纠结吗?
不妨把你的程序贴出来,速度测一下能到多少,看看有什么瓶颈。
移位操作CPU都硬件支持,就一条指令的事,剩下的就是数据的读取保存和组合,合理安排一下指令,应该是很轻松的。
CPU干这个是最快的,除非是你不想占用CPU,节省下CPU干别的。
几百个字节移位,保守估计1000个时钟周期足够了吧,1秒钟足够你刷新几万遍了,什么LED屏也不是问题。

出0入0汤圆

发表于 2019-12-23 16:40:30 | 显示全部楼层
移位位宽32位,通过进位标志判断最高bit值(只支持移1位时),应该差不多是M3最快速度了。

出0入24汤圆

发表于 2019-12-23 16:57:40 | 显示全部楼层
如果能够改成右移,有一条带进位的循环右移指令,效率会高很多

出10入0汤圆

发表于 2019-12-23 18:33:27 | 显示全部楼层
最好的办法是不移动数据,只记录要读取的偏移量。

出5入8汤圆

发表于 2019-12-23 18:46:18 | 显示全部楼层
这就是个典型的X-Y问题, 你先要说出你的目的让别人给你想办法, 而不是自己想好了思路让别人帮你按照你的思路来实现
https://coolshell.cn/articles/10804.html

出0入4汤圆

 楼主| 发表于 2019-12-23 19:07:41 | 显示全部楼层
时用在LED显示屏上的,数据向左滚动显示,所以要数据bit位移

出0入20汤圆

发表于 2019-12-23 20:03:01 | 显示全部楼层
单纯的LED话,前面几个帖子都有老法师给过答案了,直接按列输出,一次移一个字节甚至多个字节。而且以字节为单位就不需要移位了直接内存里面移动指针就好。
可以显示实际内容的LED屏幕起码8行起步,非要一行一行的刷干啥涅。
再者说了,现在主流的LED基本上都是SPI出去串行转并行,你上面那些个移位什么的都在内存里面,这个效率真的很容易做的非常高的,不如自己测一下瓶颈到底在哪里。

出0入55汤圆

发表于 2019-12-24 08:57:19 | 显示全部楼层
fbwcpu 发表于 2019-12-23 12:45
指针不能指向一个bit位吧  此方法肯定不行。

指针指向是一个byte,再用0x01<<n取出bit

出0入4汤圆

 楼主| 发表于 2019-12-24 12:36:08 来自手机 | 显示全部楼层
jssd 发表于 2019-12-24 08:57
指针指向是一个byte,再用0x01

这效率太低下了。

出0入0汤圆

发表于 2019-12-24 20:22:30 | 显示全部楼层
如果位操作比较多,可以用bitset类,可以定义位数组,提供各种位操作,包括反转,置位,复位,镜像......单片机上一样用, 用支持c++r的编泽器,比如iar 51都可以跑!

出0入8汤圆

发表于 2019-12-24 20:44:39 | 显示全部楼层
我倒觉得这题目出的很清楚了,仍然还是很多人答非所问,甚至不看题目,先来一通定性批判。
空间换时间需要pattern固定或者有限,而楼主位的移位组合有无限种,我觉得8位机上楼主的办法就是标准答案。32位ARM上可以改为32位提高速度。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-1 19:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表