由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 用什么算法能减少这个循环里的运算量?
相关主题
在matlab中如何运行不在current working directory中的script?关于那个经典的missing number的题 (转载)
what does this mean?【包子求助】20M*20M的loop怎么搞?
其实到今天也没真正搞懂数组参数的传递问题运算量较大的web service找哪个VPS?还是自己弄个服务器?
请教一个python urlopen的问题哪个框架最适合快速开发手机app后台的web service?运算量比较
Help: undefined symbol这里有人气,请教个小白问题。 (转载)
请教一个组合的算法12306 的一点思路
一个算法题用图片搜索视频有无可行性?!
多线程优化求助! (转载)问个选语言的问题
相关话题的讨论汇总
话题: va话题: vb话题: dac话题: deltadac话题: exp
进入Programming版参与讨论
1 (共1页)
l*******c
发帖数: 523
1
如果有个t的函数:
V(t) = sqrt { (Va)^2 + [(Vb)^2 - (Va)^2]*[1-e^(kt/20)]/(1-e^T)};
Va是已知的值;
Vb也是已知的值;
k, T是常数。
然后k从1到20,有没有简单的算法可以减少for循环里运算量?以下是那段code:
if (Vb > Va)
deltaDAC = (Vb * Vb - Va * Va)/(1-exp(T));
else
deltaDAC = (Va * Va - Vb * Vb)/(1-exp(T));

if (Vb > Va)
{
for (k=1; k <= 20; k++)
{
Data1 = Va * Va;
Data2 = deltaDAC * (1-exp(k/20));
DAC_Set_Value = sqrt(Data1 + Data2);
DAC_Output(DAC_Set_Value, Dir);
Delay_us(DelayTime);
}
X****r
发帖数: 3557
2
1.只看见循环,没看见递归。
2.你确定瓶颈在这个式子?每个循环你的delay就要不少时间吧?

【在 l*******c 的大作中提到】
: 如果有个t的函数:
: V(t) = sqrt { (Va)^2 + [(Vb)^2 - (Va)^2]*[1-e^(kt/20)]/(1-e^T)};
: Va是已知的值;
: Vb也是已知的值;
: k, T是常数。
: 然后k从1到20,有没有简单的算法可以减少for循环里运算量?以下是那段code:
: if (Vb > Va)
: deltaDAC = (Vb * Vb - Va * Va)/(1-exp(T));
: else
: deltaDAC = (Va * Va - Vb * Vb)/(1-exp(T));

l*******c
发帖数: 523
3
sorry,因为是DAC的关系,所以应该没有递归。Vb和Va分别是已知calibration table
里的值,look-up table就可以找到了。
你说的没错,那些delay time是由CPU的时间所决定的,这些瓶颈我没办法改。
我只是想知道,对于指数函数开平方的运算,有没有什么简单的算法,可以加快运算速度。
N***m
发帖数: 4460
4
你确定程序的瓶颈在指数开平方?

table
速度。

【在 l*******c 的大作中提到】
: sorry,因为是DAC的关系,所以应该没有递归。Vb和Va分别是已知calibration table
: 里的值,look-up table就可以找到了。
: 你说的没错,那些delay time是由CPU的时间所决定的,这些瓶颈我没办法改。
: 我只是想知道,对于指数函数开平方的运算,有没有什么简单的算法,可以加快运算速度。

y***d
发帖数: 2330
5
if either kt or T is const, you can save the exp of them.

【在 X****r 的大作中提到】
: 1.只看见循环,没看见递归。
: 2.你确定瓶颈在这个式子?每个循环你的delay就要不少时间吧?

b***i
发帖数: 3043
6
你难道不能提前算好,甚至利用编译器算好?

table
速度。

【在 l*******c 的大作中提到】
: sorry,因为是DAC的关系,所以应该没有递归。Vb和Va分别是已知calibration table
: 里的值,look-up table就可以找到了。
: 你说的没错,那些delay time是由CPU的时间所决定的,这些瓶颈我没办法改。
: 我只是想知道,对于指数函数开平方的运算,有没有什么简单的算法,可以加快运算速度。

l*******c
发帖数: 523
7
k是变量,从1到20。

【在 y***d 的大作中提到】
: if either kt or T is const, you can save the exp of them.
l*******c
发帖数: 523
8
本来是算好了,时间都满足spec.
可是现在客户改了标准,需要更快的时间内完成。不想改硬件,从新做板子了,看算法
上有没有什么可以提高的。

【在 b***i 的大作中提到】
: 你难道不能提前算好,甚至利用编译器算好?
:
: table
: 速度。

y***d
发帖数: 2330
9
save an array of 20

【在 l*******c 的大作中提到】
: k是变量,从1到20。
V********n
发帖数: 3061
10
我觉得公式的计算部分消耗的时间微乎其微,
倒是你这个output和delay很有可能是拖后腿的。
如果不需要每计算一次就output和delay的话,
那么把下面这两句尽量移到循环体外做:
DAC_Output(DAC_Set_Value, Dir);
Delay_us(DelayTime);
尤其是那个output,到底是去做了什么操作了?
不能先把结果放到一个数组里,全部算完了再输出吗?
相关主题
请教一个组合的算法关于那个经典的missing number的题 (转载)
一个算法题【包子求助】20M*20M的loop怎么搞?
多线程优化求助! (转载)运算量较大的web service找哪个VPS?还是自己弄个服务器?
进入Programming版参与讨论
l*******c
发帖数: 523
11
那个output和delay有特别的用途。为了抵消step response function 产生的ringing.

【在 V********n 的大作中提到】
: 我觉得公式的计算部分消耗的时间微乎其微,
: 倒是你这个output和delay很有可能是拖后腿的。
: 如果不需要每计算一次就output和delay的话,
: 那么把下面这两句尽量移到循环体外做:
: DAC_Output(DAC_Set_Value, Dir);
: Delay_us(DelayTime);
: 尤其是那个output,到底是去做了什么操作了?
: 不能先把结果放到一个数组里,全部算完了再输出吗?

V********n
发帖数: 3061
12
那你把下面三步合为一步,可以减少两次生成中间变量并寻址的动作,对减少时间有帮
助:
Data1 = Va * Va;
Data2 = deltaDAC * (1-exp(k/20));
DAC_Set_Value = sqrt(Data1 + Data2);
改成:
DAC_Set_Value = sqrt(Va * Va + deltaDAC * (1-exp(k/20)));
说实在的,现在的编程上很少会需要去考虑这么细微的区别。如果你真的对时间抠到纳
秒的地步,这么做也许会有点帮助。

ringing.

【在 l*******c 的大作中提到】
: 那个output和delay有特别的用途。为了抵消step response function 产生的ringing.
b***i
发帖数: 3043
13
你的公式里有t,可是代码却没有t是怎么回事?

【在 l*******c 的大作中提到】
: 如果有个t的函数:
: V(t) = sqrt { (Va)^2 + [(Vb)^2 - (Va)^2]*[1-e^(kt/20)]/(1-e^T)};
: Va是已知的值;
: Vb也是已知的值;
: k, T是常数。
: 然后k从1到20,有没有简单的算法可以减少for循环里运算量?以下是那段code:
: if (Vb > Va)
: deltaDAC = (Vb * Vb - Va * Va)/(1-exp(T));
: else
: deltaDAC = (Va * Va - Vb * Vb)/(1-exp(T));

b***i
发帖数: 3043
14
提前算好,就是利用编译器把运算结果放进数组,这样当然不用重新做板子,只是一个
代码的改变而以。象你这种就20个不同浮点数,放到数组里就是最好的方法。

【在 l*******c 的大作中提到】
: 本来是算好了,时间都满足spec.
: 可是现在客户改了标准,需要更快的时间内完成。不想改硬件,从新做板子了,看算法
: 上有没有什么可以提高的。

l*******c
发帖数: 523
15
恩,这个应该可以省一点时间。

【在 V********n 的大作中提到】
: 那你把下面三步合为一步,可以减少两次生成中间变量并寻址的动作,对减少时间有帮
: 助:
: Data1 = Va * Va;
: Data2 = deltaDAC * (1-exp(k/20));
: DAC_Set_Value = sqrt(Data1 + Data2);
: 改成:
: DAC_Set_Value = sqrt(Va * Va + deltaDAC * (1-exp(k/20)));
: 说实在的,现在的编程上很少会需要去考虑这么细微的区别。如果你真的对时间抠到纳
: 秒的地步,这么做也许会有点帮助。
:

l*******c
发帖数: 523
16
是这样的,客人随时可能给一个命令去任意一个channel (或者说voltage),而我这里为
了消除每次step response function 带来的震荡,每次从当前的voltage去到客户要求
的voltage,我都必须分20步走完。
打个比方说,从channel 1 到 channel 88, 客户可以从channel X 到任意一个channel
Y.这里面的组合太多了。所以说,我没法把每个情况都用array做,因为CPU internal
的flash memory是有限的。

【在 b***i 的大作中提到】
: 提前算好,就是利用编译器把运算结果放进数组,这样当然不用重新做板子,只是一个
: 代码的改变而以。象你这种就20个不同浮点数,放到数组里就是最好的方法。

c******e
发帖数: 545
17
Delay_us就空耗CPU时间?完全可以做点别的啊。也就是说,你在等DAC settle的这段
时间里,至少可以完成下个数值的一部分运算了
b***i
发帖数: 3043
18
把Data1的计算放循环外面,把1-e^kt这20个数放到数组里面提前算好,在循环中直接取数,少个指数运算。然后是否可以根据运算所花费的时间调整下一次等待时间?
另外你确信cache打开了?

【在 l*******c 的大作中提到】
: 如果有个t的函数:
: V(t) = sqrt { (Va)^2 + [(Vb)^2 - (Va)^2]*[1-e^(kt/20)]/(1-e^T)};
: Va是已知的值;
: Vb也是已知的值;
: k, T是常数。
: 然后k从1到20,有没有简单的算法可以减少for循环里运算量?以下是那段code:
: if (Vb > Va)
: deltaDAC = (Vb * Vb - Va * Va)/(1-exp(T));
: else
: deltaDAC = (Va * Va - Vb * Vb)/(1-exp(T));

d*1
发帖数: 24
19
这段code为什么要用if else? 不直接用绝对值?
N***m
发帖数: 4460
20
这个不会节省什么时间,而且Va Vb未必是大于0。
不过十有八九是正的。

【在 d*1 的大作中提到】
: 这段code为什么要用if else? 不直接用绝对值?
相关主题
哪个框架最适合快速开发手机app后台的web service?运算量比较用图片搜索视频有无可行性?!
这里有人气,请教个小白问题。 (转载)问个选语言的问题
12306 的一点思路挖比特币的程序是如何做到无法hack的
进入Programming版参与讨论
t****t
发帖数: 6806
21
他这个显然是firmware, 跟一般的软件不同, 就是需要比较精确的时间和速度控制

【在 V********n 的大作中提到】
: 那你把下面三步合为一步,可以减少两次生成中间变量并寻址的动作,对减少时间有帮
: 助:
: Data1 = Va * Va;
: Data2 = deltaDAC * (1-exp(k/20));
: DAC_Set_Value = sqrt(Data1 + Data2);
: 改成:
: DAC_Set_Value = sqrt(Va * Va + deltaDAC * (1-exp(k/20)));
: 说实在的,现在的编程上很少会需要去考虑这么细微的区别。如果你真的对时间抠到纳
: 秒的地步,这么做也许会有点帮助。
:

N***m
发帖数: 4460
22
你说得准没错

【在 t****t 的大作中提到】
: 他这个显然是firmware, 跟一般的软件不同, 就是需要比较精确的时间和速度控制
t****t
发帖数: 6806
23
我理解你每一步输出需要延时, 但是你说的"需要更快时间内完成"是指减短这个延时的
时间吗?
如果不是, 那是指什么时间呢?
如果是, 那你可以缩短Delay_us(DelayTime)吗?

ringing.

【在 l*******c 的大作中提到】
: 那个output和delay有特别的用途。为了抵消step response function 产生的ringing.
b***i
发帖数: 3043
24
假设他原来准备计算需要10微秒,每次输出之后等待20微秒。
他说客户改变了要求,结果每次计算需要40微秒,结果不等待都无法在规定时间内完成
任务了,所以需要优化。
解决方案很简单,把所有可以提前算好的算好,不要在循环里面计算。还有,单片机的
设置要正确,很多人cache没有打开,结果把时钟改快10倍都不够。很多情况,编译器
有问题,表达式的一种写法可以比另一种快10倍以上。多试试就好了。说必定他已经改
好了,所以不来了。

【在 t****t 的大作中提到】
: 我理解你每一步输出需要延时, 但是你说的"需要更快时间内完成"是指减短这个延时的
: 时间吗?
: 如果不是, 那是指什么时间呢?
: 如果是, 那你可以缩短Delay_us(DelayTime)吗?
:
: ringing.

l*******c
发帖数: 523
25
“需要更快时间内完成” 并不是指的减短这个输出需要的延时,这个输出需要的延时
是精心计算和对每个器件都测试的,目的是为了消除震荡的ringing。这个延时跟器件
本身的震荡周期有直接关系。
我这里指的“需要更快时间内完成”是指器件对客户的响应。
比如说,客户需要2ms内器件就要有正确的反应。这个时间包含了器件recieve command
, check look-up table, 所有运算和计算,以及送出command.

【在 t****t 的大作中提到】
: 我理解你每一步输出需要延时, 但是你说的"需要更快时间内完成"是指减短这个延时的
: 时间吗?
: 如果不是, 那是指什么时间呢?
: 如果是, 那你可以缩短Delay_us(DelayTime)吗?
:
: ringing.

l*******c
发帖数: 523
26
我还没弄好呢。今天忙娃忙了一天。
明天回去公司查查看cache。 现在用的是atmel的MCU.时钟是40MHz。

【在 b***i 的大作中提到】
: 假设他原来准备计算需要10微秒,每次输出之后等待20微秒。
: 他说客户改变了要求,结果每次计算需要40微秒,结果不等待都无法在规定时间内完成
: 任务了,所以需要优化。
: 解决方案很简单,把所有可以提前算好的算好,不要在循环里面计算。还有,单片机的
: 设置要正确,很多人cache没有打开,结果把时钟改快10倍都不够。很多情况,编译器
: 有问题,表达式的一种写法可以比另一种快10倍以上。多试试就好了。说必定他已经改
: 好了,所以不来了。

t****t
发帖数: 6806
27
所以你需要减少的是循环前面那段的时间不是么? 而不是循环内的计算.
换句话说, 你需要减少的是这段程序开始到第一个DAC_output的时间对吧. 我理解你每
两个DAC_output之间的时间是不能变的, 即Delay_us()的时间+循环内的计算时间是个
常量.
这是我一开始的预计, 但是你问的是减少"这个循环里的运算量", 所有人都被你误导了.

command

【在 l*******c 的大作中提到】
: “需要更快时间内完成” 并不是指的减短这个输出需要的延时,这个输出需要的延时
: 是精心计算和对每个器件都测试的,目的是为了消除震荡的ringing。这个延时跟器件
: 本身的震荡周期有直接关系。
: 我这里指的“需要更快时间内完成”是指器件对客户的响应。
: 比如说,客户需要2ms内器件就要有正确的反应。这个时间包含了器件recieve command
: , check look-up table, 所有运算和计算,以及送出command.

l*******c
发帖数: 523
28
是这样的,如果说器件的震荡周期是T,那倘若我能在这1个T内走越多的步数越好(现在
是20步),当步数趋于无穷是,所有的ringing将被抵消。但由于CPU的限制,1个T内所
走的步数是有限的,而如果步数不够多的话,器件产生的ringing是没法消得很干净的
。所以我现在用的是3个T的时间。换句话说,我用震荡周期的整数倍的时间来换取走的
步数变多。
如果我能减少循环体内的时间,delay_us()的时间是可以减少的(例如从3个减少到1个
T)。
当然循环体外的时间能减少也是对客户的响应时间有帮助的。

了.

【在 t****t 的大作中提到】
: 所以你需要减少的是循环前面那段的时间不是么? 而不是循环内的计算.
: 换句话说, 你需要减少的是这段程序开始到第一个DAC_output的时间对吧. 我理解你每
: 两个DAC_output之间的时间是不能变的, 即Delay_us()的时间+循环内的计算时间是个
: 常量.
: 这是我一开始的预计, 但是你问的是减少"这个循环里的运算量", 所有人都被你误导了.
:
: command

l*******c
发帖数: 523
29
在这里面,器件的震荡周期是1ms.而客户需要的响应时间是4ms. 所以这里面delay_us(
)是贡献了最多的时间消耗。可惜受CPU的limit限制,倘若在当前的CPU情况下,能改善指数开平方的运算量,在1个T内增加几倍的步数,也就是k从1到20变成1到几十而这部分的时间不变,那delayus()是可以减少2ms,那就可以满足客户的要求了。

了.

【在 t****t 的大作中提到】
: 所以你需要减少的是循环前面那段的时间不是么? 而不是循环内的计算.
: 换句话说, 你需要减少的是这段程序开始到第一个DAC_output的时间对吧. 我理解你每
: 两个DAC_output之间的时间是不能变的, 即Delay_us()的时间+循环内的计算时间是个
: 常量.
: 这是我一开始的预计, 但是你问的是减少"这个循环里的运算量", 所有人都被你误导了.
:
: command

t****t
发帖数: 6806
30
你怎么前后矛盾, 那就是说你最终的目的还是减少每一步输出的延时, 以增加循环的次
数? 那你刚才怎么说不是减短这个延时?

us(
善指数开平方的运算量,在1个T内增加几倍的步数,也就是k从1到20变成1到几十而这
部分的时间不变,那delayus()是可以减少2ms,那就可以满足客户的要求了。

【在 l*******c 的大作中提到】
: 在这里面,器件的震荡周期是1ms.而客户需要的响应时间是4ms. 所以这里面delay_us(
: )是贡献了最多的时间消耗。可惜受CPU的limit限制,倘若在当前的CPU情况下,能改善指数开平方的运算量,在1个T内增加几倍的步数,也就是k从1到20变成1到几十而这部分的时间不变,那delayus()是可以减少2ms,那就可以满足客户的要求了。
:
: 了.

相关主题
人工智能下围棋超过人类, 是一个虚假结论, 纯属误导!what does this mean?
问个 C++到C的问题其实到今天也没真正搞懂数组参数的传递问题
在matlab中如何运行不在current working directory中的script?请教一个python urlopen的问题
进入Programming版参与讨论
l*******c
发帖数: 523
31
你总结的是对的。我开始想错了,总想着在不改变delay_us()的时候,尽量加快运算速
度。

【在 t****t 的大作中提到】
: 你怎么前后矛盾, 那就是说你最终的目的还是减少每一步输出的延时, 以增加循环的次
: 数? 那你刚才怎么说不是减短这个延时?
:
: us(
: 善指数开平方的运算量,在1个T内增加几倍的步数,也就是k从1到20变成1到几十而这
: 部分的时间不变,那delayus()是可以减少2ms,那就可以满足客户的要求了。

t****t
发帖数: 6806
32
除了减少delay_us之外, 能做的就是common subexpression elimination了, 如果编译
器比较原始的话可能需要自己做, 所以你做的式子是
dac_set_value = sqrt(va*va + deltadac*(1-exp(k/20))) (有没有exp(k/20*T)?)
= sqrt(va*va + deltadac - deltadac*exp(k/20))
= sqrt(G - deltadac*exp(k/20))
其中G=va*va + deltadac, 另外如果内存够的话, exp(k/20)也可以查表, 一般内存会
比exp快一些. 也可以考虑一些近似的算法计算exp. 前提是你的20或者whatever步数是
个常数.

【在 l*******c 的大作中提到】
: 你总结的是对的。我开始想错了,总想着在不改变delay_us()的时候,尽量加快运算速
: 度。

t****t
发帖数: 6806
33
在本版混的都知道, 问问题的往往问的不是他们的本意. 最好不要替他们解释:)

【在 b***i 的大作中提到】
: 假设他原来准备计算需要10微秒,每次输出之后等待20微秒。
: 他说客户改变了要求,结果每次计算需要40微秒,结果不等待都无法在规定时间内完成
: 任务了,所以需要优化。
: 解决方案很简单,把所有可以提前算好的算好,不要在循环里面计算。还有,单片机的
: 设置要正确,很多人cache没有打开,结果把时钟改快10倍都不够。很多情况,编译器
: 有问题,表达式的一种写法可以比另一种快10倍以上。多试试就好了。说必定他已经改
: 好了,所以不来了。

l*******c
发帖数: 523
34
大牛,谢了。明天我把code改了再测测时间。

【在 t****t 的大作中提到】
: 除了减少delay_us之外, 能做的就是common subexpression elimination了, 如果编译
: 器比较原始的话可能需要自己做, 所以你做的式子是
: dac_set_value = sqrt(va*va + deltadac*(1-exp(k/20))) (有没有exp(k/20*T)?)
: = sqrt(va*va + deltadac - deltadac*exp(k/20))
: = sqrt(G - deltadac*exp(k/20))
: 其中G=va*va + deltadac, 另外如果内存够的话, exp(k/20)也可以查表, 一般内存会
: 比exp快一些. 也可以考虑一些近似的算法计算exp. 前提是你的20或者whatever步数是
: 个常数.

b***i
发帖数: 3043
35
一样的,如果1-exp(k/20)放表里面,乘法,加法,开方
G的计算反正是循环外面的。
还是楼主自己自己才能说清楚,每次等待的时间改了就行了

【在 t****t 的大作中提到】
: 除了减少delay_us之外, 能做的就是common subexpression elimination了, 如果编译
: 器比较原始的话可能需要自己做, 所以你做的式子是
: dac_set_value = sqrt(va*va + deltadac*(1-exp(k/20))) (有没有exp(k/20*T)?)
: = sqrt(va*va + deltadac - deltadac*exp(k/20))
: = sqrt(G - deltadac*exp(k/20))
: 其中G=va*va + deltadac, 另外如果内存够的话, exp(k/20)也可以查表, 一般内存会
: 比exp快一些. 也可以考虑一些近似的算法计算exp. 前提是你的20或者whatever步数是
: 个常数.

a****l
发帖数: 8211
36
比如说,如果现在的电压是0V,目标是跳到10V,你现在就让输出20步,每步上升0.5V,这样
的做法和你的做法会有什么样的不同?

【在 l*******c 的大作中提到】
: 如果有个t的函数:
: V(t) = sqrt { (Va)^2 + [(Vb)^2 - (Va)^2]*[1-e^(kt/20)]/(1-e^T)};
: Va是已知的值;
: Vb也是已知的值;
: k, T是常数。
: 然后k从1到20,有没有简单的算法可以减少for循环里运算量?以下是那段code:
: if (Vb > Va)
: deltaDAC = (Vb * Vb - Va * Va)/(1-exp(T));
: else
: deltaDAC = (Va * Va - Vb * Vb)/(1-exp(T));

t****t
发帖数: 6806
37
我觉得线性变化的电压, 从频谱上来看通常不是件好事.

【在 a****l 的大作中提到】
: 比如说,如果现在的电压是0V,目标是跳到10V,你现在就让输出20步,每步上升0.5V,这样
: 的做法和你的做法会有什么样的不同?

1 (共1页)
进入Programming版参与讨论
相关主题
问个选语言的问题Help: undefined symbol
挖比特币的程序是如何做到无法hack的请教一个组合的算法
人工智能下围棋超过人类, 是一个虚假结论, 纯属误导!一个算法题
问个 C++到C的问题多线程优化求助! (转载)
在matlab中如何运行不在current working directory中的script?关于那个经典的missing number的题 (转载)
what does this mean?【包子求助】20M*20M的loop怎么搞?
其实到今天也没真正搞懂数组参数的传递问题运算量较大的web service找哪个VPS?还是自己弄个服务器?
请教一个python urlopen的问题哪个框架最适合快速开发手机app后台的web service?运算量比较
相关话题的讨论汇总
话题: va话题: vb话题: dac话题: deltadac话题: exp