May 16, 2014 Re: range behaviour | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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. |
Copyright © 1999-2021 by the D Language Foundation