range behaviour
via Digitalmars-d
digitalmars-d at puremagic.com
Fri May 16 08:44:58 PDT 2014
On Thursday, 15 May 2014 at 13:10:29 UTC, Dicebot wrote:
> If compiler lacks contextual knowledge, than only means that
> range is not actually semantically equivalent to a loop.
Not really. Here is a simple example, a sawtooth generator that
goes from 1 to 0 with a cycle length >=2 (nyquist).
import std.algorithm;
import std.math;
struct gen_sawtooth {
enum bool empty = false;
float front;
float delta;
this(immutable float samps_per_cycle){
front = 1.0f;
delta = 1.0f/samps_per_cycle;
}
void popFront() {
front -= delta;
if(front < 0.0f) front += 1.0f;
}
}
void rangefill_sawtooth(float[] a, immutable float
samps_per_cycle){
auto gen = gen_sawtooth(samps_per_cycle);
fill(a,gen);
}
void fill_sawtooth(float[] a,immutable float samps_per_cycle) {
if(a.length==0) return;
immutable float delta = 1.0f/samps_per_cycle;
immutable max_cycle_length =
cast(uint)floor(samps_per_cycle*1.0001+1);
immutable lastcycle = a.length - max_cycle_length;
float v = 1.0f;
uint i = 0;
do {
do{ // main inner loop
a[i] = v;
++i;
v -= delta;
} while(v>=0.0f);
v += 1.0f;
} while( i < lastcycle );
for(;i<a.length;++i){ // can be optimized further
a[i] = v;
v -= delta;
if (v<0.0f) v += 1.0f;
}
}
The generated code for the range based version does not create a
fast innerloop, it lacks enough context and smarts:
fill_sawtooth main inner loop:
loop:
incl %eax
leal -2(%rax), %edx
movss %xmm1, (%rbx,%rdx,4)
subss %xmm0, %xmm1
ucomiss %xmm3, %xmm1
jae loop
rangefill_sawtooth inner loop:
loop:
movss %xmm3, (%rsi)
subss %xmm2, %xmm3
decq %rdi
ucomiss %xmm3, %xmm0
jbe skip
addss %xmm1, %xmm3
skip:
addq $4, %rsi
testq %rdi, %rdi
jne loop
> What is wrong is assumption that such kinds of loops are
> anything but tiny minority and this warrants generic "ranges
> can never be as fast as loops" statement.
Not without significant work…
>> Floating point math is inaccurate, that means the compiler
>> will have to guess what kind of accuracy you are happy with…
>
> AFAIK it is actually not true. Floating point standard defines
> basic precision guarantees
Minimum yes. That makes drift unpredictable. Sometimes you care
more about deltas than absolute values.
More information about the Digitalmars-d
mailing list