Re: avoid extra variable during void pointer cast

2017-05-17 Thread Marco Leise via Digitalmars-d-learn
Am Mon, 15 May 2017 19:30:00 +
schrieb Bauss :

> pragma(inline, true); doesn't actually do what you think it does. 
> In lining is always done whenever possible and that only tells 
> the compiler to spit out an error if it can't inline it.
 
A compiler doesn't simply inline whenever it can. A big
function that's called often would lead to massive code
duplication in that case. What I meant pragma(inline, true) to
do is overrule this cost calculation. Since the OP asked for no
extra function calls, the error on failure to inline seemed
appropriate. Cross-module inlining may fail for example on
some compiler(s) or with separate compilation.

-- 
Marco



Re: avoid extra variable during void pointer cast

2017-05-15 Thread Bauss via Digitalmars-d-learn

On Sunday, 14 May 2017 at 21:07:36 UTC, Marco Leise wrote:

Am Sun, 14 May 2017 20:18:24 +
schrieb Kevin Brogan :


[...]


No, that is not possible. An alias can only be assigned a 
symbol.



[...]


Let the compiler optimize the assignment away and don't worry 
much about it. Inlining also works well within the same module. 
In this case here I would probably use "consume" functions as I 
dub them:


import std.traits;
pragma(inline, true) /* Not really needed I hope ;) */
ref T consume(T)(ref void* data) if (!hasIndirections!T)
{
T* ptr = cast(T*)data;
data += T.sizeof;
return *ptr;
}

You can then rewrite your addInt function like this:

void add(T)(void* state, void* data) if (isNumeric!T)
{
state.consume!T += data.consume!T;
}


pragma(inline, true); doesn't actually do what you think it does. 
In lining is always done whenever possible and that only tells 
the compiler to spit out an error if it can't inline it.




Re: avoid extra variable during void pointer cast

2017-05-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 14 May 2017 at 22:00:58 UTC, Stanislav Blinov wrote:

[...]

Yep, it's an alias to template function instantiation, that is, 
concrete function - a symbol.


Yes, my bad :(



But of course, it *is* going to be called on every 
"dereference". GDC optimizes the call away starting at -O1, LDC 
needs -O2. DMD makes temporaries :)


Which just reinforces my personal mantra: Develop with dmd, 
release with ldc or gdc.


Re: avoid extra variable during void pointer cast

2017-05-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 14 May 2017 at 21:55:01 UTC, ag0aep6g wrote:

On 05/14/2017 11:35 PM, Moritz Maxeiner wrote:

On Sunday, 14 May 2017 at 21:16:04 UTC, Stanislav Blinov wrote:

[...]

T* ptrCast(T, alias ptr)() { return cast(T*)ptr; }

[...]

alias _state = ptrCast!(int, state);

[...]
That's a pretty cool workaround, but not an alias to the cast, 
but an

alias to a parametrized function template (a type),


Not sure if I'm reading that right, but `_state` is not an 
alias of a (parametrized function) template.


The template instantiation results in a function. `_state` is 
an alias of that function. `alias foo = ptrCast;` would make an 
alias of the template. Neither of them is a type.


You're right. I forgot about the alias to a symbol rule (event 
though I myself just linked to it :/ ). Sorry about that.


Re: avoid extra variable during void pointer cast

2017-05-14 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 14 May 2017 at 21:55:01 UTC, ag0aep6g wrote:

On 05/14/2017 11:35 PM, Moritz Maxeiner wrote:

On Sunday, 14 May 2017 at 21:16:04 UTC, Stanislav Blinov wrote:

[...]

T* ptrCast(T, alias ptr)() { return cast(T*)ptr; }

[...]

alias _state = ptrCast!(int, state);

[...]
That's a pretty cool workaround, but not an alias to the cast, 
but an

alias to a parametrized function template (a type),


Not sure if I'm reading that right, but `_state` is not an 
alias of a (parametrized function) template.


The template instantiation results in a function. `_state` is 
an alias of that function. `alias foo = ptrCast;` would make an 
alias of the template. Neither of them is a type.


Yep, it's an alias to template function instantiation, that is, 
concrete function - a symbol.


But of course, it *is* going to be called on every "dereference". 
GDC optimizes the call away starting at -O1, LDC needs -O2. DMD 
makes temporaries :)


Re: avoid extra variable during void pointer cast

2017-05-14 Thread ag0aep6g via Digitalmars-d-learn

On 05/14/2017 11:35 PM, Moritz Maxeiner wrote:

On Sunday, 14 May 2017 at 21:16:04 UTC, Stanislav Blinov wrote:

[...]

T* ptrCast(T, alias ptr)() { return cast(T*)ptr; }

[...]

alias _state = ptrCast!(int, state);

[...]

That's a pretty cool workaround, but not an alias to the cast, but an
alias to a parametrized function template (a type),


Not sure if I'm reading that right, but `_state` is not an alias of a 
(parametrized function) template.


The template instantiation results in a function. `_state` is an alias 
of that function. `alias foo = ptrCast;` would make an alias of the 
template. Neither of them is a type.


Re: avoid extra variable during void pointer cast

2017-05-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 14 May 2017 at 21:16:04 UTC, Stanislav Blinov wrote:

On the point of "not possible...", "only a symbol...", etc:

T* ptrCast(T, alias ptr)() { return cast(T*)ptr; }

void addInt(void* state, void* data)
{
alias _state = ptrCast!(int, state);
alias _data = ptrCast!(int, data);

static assert(!is(typeof(_state) == int*));
static assert(!is(typeof(_data) == int*));

*_state += *_data;
}


That's a pretty cool workaround, but not an alias to the cast, 
but an alias to a parametrized function template (a type), so I 
will stick to my statement of "not possible". AFAIK, this would 
also invoke the respective function template instance for ptrCast 
every time _state or _data are referenced, so if we're going with 
the spirit of the question that's still going to be horrible if 
the compiler doesn't optimize ;p




Re: avoid extra variable during void pointer cast

2017-05-14 Thread Stanislav Blinov via Digitalmars-d-learn

On the point of "not possible...", "only a symbol...", etc:

T* ptrCast(T, alias ptr)() { return cast(T*)ptr; }

void addInt(void* state, void* data)
{
alias _state = ptrCast!(int, state);
alias _data = ptrCast!(int, data);

static assert(!is(typeof(_state) == int*));
static assert(!is(typeof(_data) == int*));

*_state += *_data;
}

But take heed to the compiler optimization advice. DMD generates 
pretty horrendous code for this. LDC does rather well though. 
Since speed matters, always look at the assembly. Look at it even 
if it doesn't ;)


Re: avoid extra variable during void pointer cast

2017-05-14 Thread Mike B Johnson via Digitalmars-d-learn

On Sunday, 14 May 2017 at 20:18:24 UTC, Kevin Brogan wrote:

I have a piece of code that takes a callback function.

The callback has the signature void callback(void* state, void* 
data)


There are several of these functions. All of them use state and 
data as differing types.


As an example, let's look at one that uses both of them as int*.

addInt(void* state, void* data)
{
*cast(int*)state += *cast(int*)data;
}

Is it not possible to specify the cast as an alias so that I 
can declare the cast once at the beginning of the function?


Something like this?

addInt(void* state, void* data)
{
alias _state = cast(int*)state; // Error: basic type 
expected, not cast
alias _data = cast(int*)data; // Error: basic type 
expected, not cast


*_state += *_data;
}

I can always do this:

addInt(void* state, void* data)
{
int* _state = cast(int*)state;
int* _data = cast(int*)data;

*_state += *_data;
}

But I don't want to create a new variable and assign it 
everytime I call the function. The examples I'm using are 
contrived, but in the c code I am porting this from, the 
callback gets called thousands of times a second, every 
optimization matters, and the variables are used many times per 
function. I don't want to riddle the code with casts if i can 
avoid it and I don't want to create and destroy useless proxy 
variables every time the function is called.


1. Use template, that is what they are for

addInt(A, B)(A* state, B* data)
{
static if(is(B == int))
{
   // B is an int if this block is called so no reason to 
cast.

}
}

2. Use overloads, basically same as templates.

addInt(int* state, int* data)
{

}

3. Don't worry about it, any extra temp variables will almost 
surely be optimized away.




Re: avoid extra variable during void pointer cast

2017-05-14 Thread Marco Leise via Digitalmars-d-learn
Am Sun, 14 May 2017 20:18:24 +
schrieb Kevin Brogan :

> I have a piece of code that takes a callback function.
> 
> The callback has the signature void callback(void* state, void* 
> data)
> 
> There are several of these functions. All of them use state and 
> data as differing types.
> 
> As an example, let's look at one that uses both of them as int*.
> 
> addInt(void* state, void* data)
> {
>  *cast(int*)state += *cast(int*)data;
> }
> 
> Is it not possible to specify the cast as an alias so that I can 
> declare the cast once at the beginning of the function?
> 
> Something like this?
> 
> addInt(void* state, void* data)
> {
>  alias _state = cast(int*)state; // Error: basic type 
> expected, not cast
>  alias _data = cast(int*)data; // Error: basic type expected, 
> not cast
> 
>  *_state += *_data;
> }

No, that is not possible. An alias can only be assigned a
symbol.

> I can always do this:
> 
> addInt(void* state, void* data)
> {
>  int* _state = cast(int*)state;
>  int* _data = cast(int*)data;
> 
>  *_state += *_data;
> }
> 
> But I don't want to create a new variable and assign it everytime 
> I call the function. The examples I'm using are contrived, but in 
> the c code I am porting this from, the callback gets called 
> thousands of times a second, every optimization matters, and the 
> variables are used many times per function. I don't want to 
> riddle the code with casts if i can avoid it and I don't want to 
> create and destroy useless proxy variables every time the 
> function is called.

Let the compiler optimize the assignment away and don't worry
much about it. Inlining also works well within the same module.
In this case here I would probably use "consume" functions as
I dub them:

import std.traits;
pragma(inline, true) /* Not really needed I hope ;) */
ref T consume(T)(ref void* data) if (!hasIndirections!T)
{
T* ptr = cast(T*)data;
data += T.sizeof;
return *ptr;
}

You can then rewrite your addInt function like this:

void add(T)(void* state, void* data) if (isNumeric!T)
{
state.consume!T += data.consume!T;
}

-- 
Marco



Re: avoid extra variable during void pointer cast

2017-05-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 14 May 2017 at 20:18:24 UTC, Kevin Brogan wrote:

I have a piece of code that takes a callback function.

The callback has the signature void callback(void* state, void* 
data)


There are several of these functions. All of them use state and 
data as differing types.


As an example, let's look at one that uses both of them as int*.

addInt(void* state, void* data)
{
*cast(int*)state += *cast(int*)data;
}

Is it not possible to specify the cast as an alias so that I 
can declare the cast once at the beginning of the function?


Something like this?

addInt(void* state, void* data)
{
alias _state = cast(int*)state; // Error: basic type 
expected, not cast
alias _data = cast(int*)data; // Error: basic type 
expected, not cast


*_state += *_data;
}

I can always do this:

addInt(void* state, void* data)
{
int* _state = cast(int*)state;
int* _data = cast(int*)data;

*_state += *_data;
}

But I don't want to create a new variable and assign it 
everytime I call the function. The examples I'm using are 
contrived, but in the c code I am porting this from, the 
callback gets called thousands of times a second, every 
optimization matters, and the variables are used many times per 
function. I don't want to riddle the code with casts if i can 
avoid it and I don't want to create and destroy useless proxy 
variables every time the function is called.


First: Any decent compiler will optimize both the variable 
_state, as well as the variable _data out[1][2], this sounds like 
a classic case of *evil* early optimization. Trust your compiler 
to get it right; and if you're not sure, check the generated 
assembly.
Second: No, it is not possible, because an alias is a symbol that 
stands in for another type[3], not for an expression.


[1] https://godbolt.org/g/X4D02i
[2] https://godbolt.org/g/6i52Tt
[3] https://dlang.org/spec/declaration.html#alias


avoid extra variable during void pointer cast

2017-05-14 Thread Kevin Brogan via Digitalmars-d-learn

I have a piece of code that takes a callback function.

The callback has the signature void callback(void* state, void* 
data)


There are several of these functions. All of them use state and 
data as differing types.


As an example, let's look at one that uses both of them as int*.

addInt(void* state, void* data)
{
*cast(int*)state += *cast(int*)data;
}

Is it not possible to specify the cast as an alias so that I can 
declare the cast once at the beginning of the function?


Something like this?

addInt(void* state, void* data)
{
alias _state = cast(int*)state; // Error: basic type 
expected, not cast
alias _data = cast(int*)data; // Error: basic type expected, 
not cast


*_state += *_data;
}

I can always do this:

addInt(void* state, void* data)
{
int* _state = cast(int*)state;
int* _data = cast(int*)data;

*_state += *_data;
}

But I don't want to create a new variable and assign it everytime 
I call the function. The examples I'm using are contrived, but in 
the c code I am porting this from, the callback gets called 
thousands of times a second, every optimization matters, and the 
variables are used many times per function. I don't want to 
riddle the code with casts if i can avoid it and I don't want to 
create and destroy useless proxy variables every time the 
function is called.