这是一个简单的逻辑编程和优化练习曲,是我为自己创建的,有点偶然发现了它。
我有一个简单方案的数值模拟。考虑一些蓄水池(或电容器)Cm
,它不断地增加压力。让我们调用它的当前状态Vm
:
在它的输出端,它有一个阀门或门,G
,可以根据以下逻辑打开或关闭:
- 门打开,当压力(或电压)
Vm
超过某个阈值时,称之为 Vopen
:Vm > Vopen
- 门保持打开状态,而电流输出
Ia
大于一些 Ihold
:Ia > IHold
- 栅极仅从储层中传导能量(如二极管)
我正在对此进行数值 ODE 求解,即在每个(相等的、小的)时间步长 dt 处确定 Vm
和 Ia
。有这三个变体:
变量类型:
float Vm=0.0, Ia=0.0, Vopen, Ihold, Ra, dt;
int G=0;
循环体 v1(串行):
Vm = Vm + (-Ia*G)*dt;
G |= (Vm > Vopen);
Ia = Ia + (Vm*Ra*G)*dt;
G &= (Ia > Ihold);
循环体 v2(串行,带临时变量,三元条件):
int Gv; // temporary var
Vm = Vm + (-Ia*G)*dt;
Gv = (Vm > Vopen) ? 1 : G;
Ia = Ia + (Vm*Ra*Gv)*dt;
G = (Ia > Ihold) ? Gv : 0;
循环体 v3(并行,带缓存):
// cache new state first
float Vm1 = Vm + (-Ia*G)*dt;
float Ia1 = Ia + (Vm*Ra*G)*dt;
// update memory
G = ( Vm1 > Vopen ) || (( Ia1 > Ihold ) && G);
Vm = Vm1;
Ia = Ia1; // not nesesary to cache, done for readibility
G 取自建立以下真值表,再加上想象:
问:
- 哪个是正确的?是吗?
- 第三种变体(并行逻辑)与前两种(串行逻辑)有何不同?
- 是否有更有效的方法来执行此逻辑?
附言。我正在尝试针对 SSE 优化它,然后(单独)针对 OpenCL(如果给出优化提示)
PPS。对于那些好奇的人,这里是my working simulator , 涉及这个门 (html/js)
我是一名优秀的程序员,十分优秀!