Creating a new type, to get strong-ish type checking and restrict usage to certain operations, using struct perhaps

2017-07-21 Thread Cecil Ward via Digitalmars-d-learn
I was think about how to create a new type that holds packed bcd 
values, of a choice of widths, that must fit into a uint32_t or a 
uint64_t (not really long multi-byte objects). I am not at all 
sure how to do it. I thought about using a templated struct to 
simply wrap a uint of a chosen width, and perhaps use alias this 
to make things nicer.




Re: Creating a new type, to get strong-ish type checking and restrict usage to certain operations, using struct perhaps

2017-07-21 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 21 July 2017 at 18:49:21 UTC, Cecil Ward wrote:
I was think about how to create a new type that holds packed 
bcd values, of a choice of widths, that must fit into a 
uint32_t or a uint64_t (not really long multi-byte objects). I 
am not at all sure how to do it. I thought about using a 
templated struct to simply wrap a uint of a chosen width, and 
perhaps use alias this to make things nicer.


I guess part of my question, which I didn't really highlight well 
enough, is the issue of strong typing. Example: physical units 
types, such as amps and volts, implemented as say a double or 
float or real (want to template that) but disallow evil 
assignments, comparisons, addition etc of mixed types. Another 
one would be the prevention of mixing pounds and pence by 
straight addition, or straight comparisons and blocking straight 
assignment. I'm assuming in the latter case you might use a 
machine-architecture native integral type of whatever width, 
again templating wanted. These are all really old requests, I'm 
sure, but I would appreciate a start as to how to implement the 
strong type checking in D without too much pain.


Going back to the original example of packed bcd stored in a 
uint64_t say, first thing is that I want to ban illegal mixing of 
arbitrary binary values in ordinary uint64_tmtypes with decimal 
types, again no assignment, addition, comoarisons etc across 
types at all allowed. And no friendly automagically conversions 
from packed bcd to binary on the fly either - I want to treat 
that kind of usage as a straight bug by the user, for the moment 
at least, anyway, as I don't want to encourage silent horrible 
inefficiency creeping in.


Re: Creating a new type, to get strong-ish type checking and restrict usage to certain operations, using struct perhaps

2017-07-21 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 22 July 2017 at 03:18:29 UTC, Cecil Ward wrote:

[...]


I saw David Nadlinger's units package. I'd like to know how the 
strong typing works.


Bug or not? Statics inside blocks

2017-07-28 Thread Cecil Ward via Digitalmars-d-learn
The snippet below failed to compile (I think) in the latest DMD - 
but I can't see the error message in the web-based editor at 
dlang.org. It certainly failed to compile under GDC 5.2.0 when 
tried out using d.godbolt.org. (Is there any chance of a later 
GDC compiler there?)


Is it my bug, or a compiler bug? (name clash at link-time?):

void main()
{
{
immutable static dstring str1 = "a";
}
{
immutable static dstring str1 = "b";
}
}


Re: Bug or not? Statics inside blocks

2017-07-28 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 29 July 2017 at 01:54:29 UTC, Cecil Ward wrote:
The snippet below failed to compile (I think) in the latest DMD 
- but I can't see the error message in the web-based editor at 
dlang.org. It certainly failed to compile under GDC 5.2.0 when 
tried out using d.godbolt.org. (Is there any chance of a later 
GDC compiler there?)


Is it my bug, or a compiler bug? (name clash at link-time?):

void main()
{
{
immutable static dstring str1 = "a";
}
{
immutable static dstring str1 = "b";
}
}


Workaround is just to rename one, assuming that avoids a name 
clash at -time.


Specify rhs at initialisation or assignment of typedef' d variable

2017-07-31 Thread Cecil Ward via Digitalmars-d-learn
Say I have used Typedef! to create some new type and I declare a 
variable, constant or enum of that type. Is there a way that I 
can express a literal value on the rhs without having to use 
casts, as that seems to defeat the point of the nice type safety?


I may be asking for the impossible or _illogical_ here. In any 
case, I still get to keep the nice feature of not being able to 
mix up types with assignment from one variable to another.


Specific example is

mac_addr_48_t   my_mac_address = 0x112233445566uL;

Which now produces a compile time error after I changed to use an 
alias  = Typedef!uint64_t as opposed to just a straight alias = 
uint64_t earlier with no strong typing.


Re: Specify rhs at initialisation or assignment of typedef' d variable

2017-07-31 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 31 July 2017 at 07:50:57 UTC, inevzxui wrote:

On Monday, 31 July 2017 at 07:16:25 UTC, Cecil Ward wrote:
Say I have used Typedef! to create some new type and I declare 
a variable, constant or enum of that type. Is there a way that 
I can express a literal value on the rhs without having to use 
casts, as that seems to defeat the point of the nice type 
safety?


I may be asking for the impossible or _illogical_ here. In any 
case, I still get to keep the nice feature of not being able 
to mix up types with assignment from one variable to another.


Specific example is

mac_addr_48_t   my_mac_address = 0x112233445566uL;

Which now produces a compile time error after I changed to use 
an alias  = Typedef!uint64_t as opposed to just a straight 
alias = uint64_t earlier with no strong typing.


If struct + alias this is not strong enough the only solution 
is see is a helper template à la "octal" or "hexString", i.e a 
static cally checked string.


I suspect that I am asking for something that literally makes no 
sense at all. I wanted to try and avoid opening the door to 
allowing the following kind of typing error now, eg

enum ip_address = 0x11223344;
mac_addr_48_t my_mac = cast(mac_addr_48_t) ip_address;
as if we are going to the bother of introducing strong type 
checking with Typedef! then the last thing I want to do is 
encourage is a proliferation of casts.


I realise something else now too -

Issue 2: The thing is that I also immediately have to do a lot of 
work to make the simplest operators work anyway, such as in


foreach( addr;  base_mac_address .. base_mac_address + range )

where the + operator is producing compile-time errors now.

So it just seems that the Typedef! feature immediately make life 
into a nightmare. I don't know if something based of the physical 
units module (using 'dimensionless' in this case) would work - 
perhaps it only handles floating point of various types? Or 
whether that would also involve a huge amount of work and still 
have issue 1 mentioned earlier. In any case, I have absolutely no 
clue how to even begin to start using the units module thing.


Re: Specify rhs at initialisation or assignment of typedef' d variable

2017-07-31 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 31 July 2017 at 08:53:10 UTC, Cecil Ward wrote:

On Monday, 31 July 2017 at 07:50:57 UTC, inevzxui wrote:

[...]


I suspect that I am asking for something that literally makes 
no sense at all. I wanted to try and avoid opening the door to 
allowing the following kind of typing error now, eg

enum ip_address = 0x11223344;
mac_addr_48_t my_mac = cast(mac_addr_48_t) ip_address;
as if we are going to the bother of introducing strong type 
checking with Typedef! then the last thing I want to do is 
encourage is a proliferation of casts.


[...]


Actually, it would be really nice to have some kind of safe 
initialisation helper that checks value ranges, as in this 
particular case I need to make sure that the literal 64-bit value 
fits in 48 bits.


Re: (SIMD) Optimized multi-byte chunk scanning

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 25 August 2017 at 18:52:57 UTC, Nordlöw wrote:

On Friday, 25 August 2017 at 09:40:28 UTC, Igor wrote:
As for a nice reference of intel intrinsics: 
https://software.intel.com/sites/landingpage/IntrinsicsGuide/


Wow, what a fabulous UX!


The pcmpestri instruction is probably what you are looking for? 
There is a useful resource in the Intel optimisation guide. There 
is also an Intel article about speeding up XML parsing with this 
instruction, but if memory serves it's really messy - a right 
palaver. A lot depends on how much control, if any you have over 
the input data, typically none I quite understand.


Based on this article,
https://graphics.stanford.edu/~seander/bithacks.html
I wrote a short d routine to help me learn the language as I was 
thinking about faster strlen using larger-sized gulps. The above 
article has a good test for whether or not a wide word contains a 
particular byte value somewhere in it. I wrote a

   bool hasZeroByte( in uint64_t x )
function based on that method.

I'm intending to write a friendlier d convenience routine to give 
access to inline pcmpestri code generation in GDC when I get 
round to it (one instruction all fully inlined and flexibly 
optimised at compile-time, with no subroutine call to an 
instruction).


Agner Fog's libraries and articles are superb, take a look. He 
must have published code to deal with these C standard library 
byte string processing functions efficiently with wide aligned 
machine words, unless I'm getting very forgetful.


A bit of googling?


No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn
I have a pure function that has constant inputs, known at 
compile-time, contains no funny stuff internally - looked at the 
generated code, and no RTL calls at all. But in a test call with 
constant literal values (arrays initialised to literal) passed to 
the pure routine GDC refuses to CTFE the whole thing, as I would 
expect it (based on previous experience with d and GDC) to simply 
generate a trivial function that puts out a block of 
CTFE-evaluated constant data corresponding to the input.


Unfortunately it's a bit too long to post in here. I've tried 
lots of variations. Function is marked nogc safe pure nothrow


Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation? Haven't 
tried DMD yet. Can try LDC. Am using d.godbolt.org to look at the 
result, as I don't have a machine here to run a d compiler on.


Other things I can think of. Contains function-in-a-function 
calls, which are all unlined out in the generated code nicely, 
and not the first time I've done that with GDC either.


Switches: Am using -Os or -O2 or -O3 - tried all. Tuning to 
presume + enable the latest x86-64 instructions. release build, 
no bounds-checks.


Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 18:16:07 UTC, ag0aep6g wrote:

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation?


That's not how CTFE works. CTFE only kicks in when the *result* 
is required at compile time. For example, when you assign it to 
an enum. The inputs must be known at compile time, and the 
interpreter will refuse to go on when you try something impure. 
But those things don't trigger CTFE.


The compiler may choose to precompute any constant expression, 
but that's an optimization (constant folding), not CTFE.


I think I understand, but I'm not sure. I should have explained 
properly. I suspect what I should have said was that I was 
expecting an _optimisation_ and I didn't see it. I thought that a 
specific instance of a call to my pure function that has all 
compile-time-known arguments would just produce generated code 
that returned an explicit constant that is worked out by CTFE 
calculation, replacing the actual code for the general function 
entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should have 
been replaced by generated x64 code looking exactly literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length literal 
array of 32-but numbers in my case (no dynamic arrays anywhere, 
these I believe potentially involve RTL calls and the allocator 
internally).


Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

On Saturday, 26 August 2017 at 18:16:07 UTC, ag0aep6g wrote:

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation?


That's not how CTFE works. CTFE only kicks in when the 
*result* is required at compile time. For example, when you 
assign it to an enum. The inputs must be known at compile 
time, and the interpreter will refuse to go on when you try 
something impure. But those things don't trigger CTFE.


The compiler may choose to precompute any constant expression, 
but that's an optimization (constant folding), not CTFE.


I think I understand, but I'm not sure. I should have explained 
properly. I suspect what I should have said was that I was 
expecting an _optimisation_ and I didn't see it. I thought that 
a specific instance of a call to my pure function that has all 
compile-time-known arguments would just produce generated code 
that returned an explicit constant that is worked out by CTFE 
calculation, replacing the actual code for the general function 
entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should 
have been replaced by generated x64 code looking exactly 
literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length literal 
array of 32-but numbers in my case (no dynamic arrays anywhere, 
these I believe potentially involve RTL calls and the allocator 
internally).


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the algorithm 
at runtime is a performance disaster when it certainly could have 
all been thrown away in the particular case in point and been 
replaced by a return of a precomputed value with zero runtime 
cost. So this is actually an issue with specific compilers, but I 
was wondering if I have missed anything about any D general rules 
that make CTFE evaluation practically impossible?


Re: No CTFE of function

2017-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 23:53:36 UTC, Cecil Ward wrote:

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

[...]


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the algorithm 
at runtime is a performance disaster when it certainly could 
have all been thrown away in the particular case in point and 
been replaced by a return of a precomputed value with zero 
runtime cost. So this is actually an issue with specific 
compilers, but I was wondering if I have missed anything about 
any D general rules that make CTFE evaluation practically 
impossible?


I suspect I posted this in the wrong category completely, should 
have been under GDC (poss applies to LDC too, will test that)


Re: No CTFE of function

2017-08-27 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 27 August 2017 at 00:20:47 UTC, ag0aep6g wrote:

On 08/27/2017 01:53 AM, Cecil Ward wrote:

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

[...]
I think I understand, but I'm not sure. I should have 
explained properly. I suspect what I should have said was 
that I was expecting an _optimisation_ and I didn't see it. I 
thought that a specific instance of a call to my pure 
function that has all compile-time-known arguments would just 
produce generated code that returned an explicit constant 
that is worked out by CTFE calculation, replacing the actual 
code for the general function entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should 
have been replaced by generated x64 code looking exactly 
literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length 
literal array of 32-but numbers in my case (no dynamic arrays 
anywhere, these I believe potentially involve RTL calls and 
the allocator internally).


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the 
algorithm at runtime is a performance disaster when it 
certainly could have all been thrown away in the particular 
case in point and been replaced by a return of a precomputed 
value with zero runtime cost. So this is actually an issue 
with specific compilers, but I was wondering if I have missed 
anything about any D general rules that make CTFE evaluation 
practically impossible?


I don't know what might prevent the optimization.

You can force (actual) CTFE with an enum or static variable.
Then you don't have to rely on the optimizer. And the compiler 
will reject the code if you try something that can't be done at 
compile time.


Example:

auto foo() { enum r = bar(2, 3); return r; }


Please don't use the term "CTFE" for the optimization. The two 
are related, of course. The optimizer may literally evaluate 
functions at compile time. But I think we better reserve the 
acronym "CTFE" for the guaranteed/forced kind of 
precomputation, to avoid confusion.


Static had already been tried. Failed. Thanks to your tip, I 
tried enum next. Failed as well, wouldn't compile with GDC.


I tried LDC, which did the right thing in all cases. Optimised 
correctly in every use case to not compute in the generated code, 
just return the literal compile-time calculated result array by 
writing a load of immediate values straight to the destination. 
Hurrah for LDC.


Then tried DMD via web-based edit/compile feature at dlang.org 
website. Refused to compile in the enum case and actually told me 
why, in a very very cryptic way. I worked out that it has a 
problem internally (this is a now an assignment into an enum, so 
I have permission to use the term CTFE now) in that it refuses to 
do CTFE if any variable is declared using an =void initialiser to 
stop the wasteful huge pre-fill with zeros which could take half 
an hour on a large object with slow memory and for all I know 
play havoc with the cache. So simply deleting the = void fixed 
the problem with DMD.


So that's it. There are unknown random internal factors that 
prevent CTFE or CTFE-type optimisation.


I had wondered if pointers might present a problem. The function 
in question originally was specced something like

pure nothrow @nogc @safe
void pure_compute( result_t * p_result, in input_t x )

and just as a test, I tried changing it to

result_t  pure_compute( in input_t x )

instead. I don't think it makes any difference though. I 
discovered the DMD -void thing at that point so this was not 
checked out properly.


Your enum tip was very helpful.

Ps
GDC errors: Another thing that has wasted a load of time is that 
GDC signals errors on lines where there is a function call that 
is fine, yet the only problem is in the body of the function that 
is _being_ called itself, and fixing the function makes the 
phantom error at the call-site go away. This nasty behaviour has 
you looking for errors at and before the call-site, or thinking 
you have the spec of the call args wrong or incorrect types. 
[Compiler-Explorer problem : I am perhaps blaming GDC unfairly, 
because I have only ever used it through the telescope that is 
d.godbolt.org and I am assuming that reports errors on the 
correct source lines. It doesn't show error message text tho, 
which is a nightmare, but nothing to do with the compiler 
obviously.]





Re: No CTFE of function

2017-08-27 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 27 August 2017 at 17:36:54 UTC, Cecil Ward wrote:

On Sunday, 27 August 2017 at 00:20:47 UTC, ag0aep6g wrote:

[...]


Static had already been tried. Failed. Thanks to your tip, I 
tried enum next. Failed as well, wouldn't compile with GDC.


[...]


I wonder if there is anything written up anywhere about what 
kinds of things are blockers to either CTFE or to successful 
constant-folding optimisation in particular compilers or in 
general?


Would be useful to know what to stay away from if you really need 
to make sure that horrendously slow code does not get run at 
runtime. Sometimes it is possible or even relatively easy to 
reorganise things and do without certain practices in order to 
win such a massive reward.


Re: No CTFE of function

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 27 August 2017 at 00:08:45 UTC, Jonathan M Davis wrote:

[...]


Indeed. I used the term CTFE too loosely.


Re: No CTFE of function

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 28 August 2017 at 03:16:24 UTC, Mike Parker wrote:

On Sunday, 27 August 2017 at 17:47:54 UTC, Cecil Ward wrote:

[...]


The rules for CTFE are outlined in the docs [1]. What is 
described there is all there is to it. If those criteria are 
not met, the function cannot be executed at compile time. More 
importantly, as mentioned earlier in the thread, CTFE will only 
occur if a function *must* be executed at compile time, i.e. it 
is in a context where the result of the function is required at 
compile-time. An enum declaration is such a situation, a 
variable initialization is not.


[...]


Those links are extremely useful. Many thanks. Because I am full 
of NHS pain drugs, I am pretty confused half the time, and so 
finding documentation is difficult for me through the haze, so 
much appreciated. RTFM of course applies as always.


Re: No CTFE of function

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 26 August 2017 at 16:52:36 UTC, Cecil Ward wrote:
I have a pure function that has constant inputs, known at 
compile-time, contains no funny stuff internally - looked at 
the generated code, and no RTL calls at all. But in a test call 
with constant literal values (arrays initialised to literal) 
passed to the pure routine GDC refuses to CTFE the whole thing, 
as I would expect it (based on previous experience with d and 
GDC) to simply generate a trivial function that puts out a 
block of CTFE-evaluated constant data corresponding to the 
input.


Unfortunately it's a bit too long to post in here. I've tried 
lots of variations. Function is marked nogc safe pure nothrow


Any ideas as to why GDC might just refuse to do CTFE on 
compile-time-known inputs in a truly pure situation? Haven't 
tried DMD yet. Can try LDC. Am using d.godbolt.org to look at 
the result, as I don't have a machine here to run a d compiler 
on.


Other things I can think of. Contains function-in-a-function 
calls, which are all unlined out in the generated code nicely, 
and not the first time I've done that with GDC either.


Switches: Am using -Os or -O2 or -O3 - tried all. Tuning to 
presume + enable the latest x86-64 instructions. release build, 
no bounds-checks.


I will henceforth use the enum trick advice all times.

I noticed that the problem with init =void is compiler-dependent. 
Using an enum for real CTFE, I don't get error messages from LDC 
or GDC (i.e. [old?] versions currently up on d.godbolt.org) x64 
compilers even if I do use the =void optimisation. This saved a 
totally wasteful and pointless zero-fill of 64 bytes using 2 YMM 
instructions in the particular unit test case I had, but of 
course could easily be dramatically bad news depending on the 
array size I am unnecessarily filling.


Re: Output range with custom string type

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 28 August 2017 at 14:27:19 UTC, Jacob Carlborg wrote:
I'm working on some code that sanitizes and converts values of 
different types to strings. I thought it would be a good idea 
to wrap the sanitized string in a struct to have some type 
safety. Ideally it should not be possible to create this type 
without going through the sanitizing functions.


The problem I have is that I would like these functions to push 
up the allocation decision to the caller. Internally these 
functions use formattedWrite. I thought the natural design 
would be that the sanitize functions take an output range and 
pass that to formattedWrite.


Here's a really simple example:

import std.stdio : writeln;

struct Range
{
void put(char c)
{
writeln(c);
}
}

void sanitize(OutputRange)(string value, OutputRange range)
{
import std.format : formattedWrite;
range.formattedWrite!"'%s'"(value);
}

void main()
{
Range range;
sanitize("foo", range);
}

The problem now is that the data is passed one char at the time 
to the range. Meaning that if the user implements a custom 
output range, the user is in full control of the data. It will 
now be very easy for the user to make a mistake or manipulate 
the data on purpose. Making the whole idea of the sanitized 
type pointless.


Any suggestions how to fix this or a better idea?


Q is it an option to let the caller provide all the storage in an 
oversized fixed-length buffer? You could add a second helper 
function to compute and return a suitable safely pessimistic ott 
max value for the length reqd which could be called once 
beforehand to establish the reqd buffer size (or check it). This 
is the technique I am using right now. My sizing function is 
ridiculously fast as I am lucky in the particular use-case.


General performance tip about possibly using the GC or not

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn
I am vacillating - considering breaking a lifetime's C habits and 
letting the D garbage collector make life wonderful by just 
cleaning up after me and ruining my future C disciple by not 
deleting stuff myself.


I don't know when the GC actually gets a chance to run.

I am wondering if deleting the usual bothersome 
immediately-executed hand-written cleanup code could actually 
improve performance in a sense in some situations. If the cleanup 
is done later by the GC, then this might be done when the 
processor would otherwise be waiting for io, in the top loop of 
an app, say? And if so this would amount to moving the code to be 
run effectively like 'low priority' app-scheduled activities, 
when the process would be waiting anyway, so moving cpu cycles to 
a later time when it doesn't matter. Is this a reasonable picture?


If I carry on deleting objects / freeing / cleaning up as I'm 
used to, without disabling the GC, am I just slowing my code 
down? Plus (for all I know) the GC will use at least some battery 
or possibly actually important cpu cycles in scanning and finding 
nothing to do all the time because I've fully cleaned up.


I suppose there might also be a difference in cache-friendliness 
as cleaning up immediately by hand might be working on hot 
memory, but the GC scanner coming along much later might have to 
deal with cold memory, but it may not matter if the activity is 
app-scheduled like low priority work or is within time periods 
that are merely eating into io-bound wait periods anyway.


I definitely need to read up on this. Have never used a GC 
language, just decades of C and mountains of asm.


Any general guidance on how to optimise cpu usage particularly 
responsiveness.


One pattern I used to use when writing service processes (server 
apps) is that of deferring compute tasks by using a kind of 'post 
this action' which adds an entry into a queue, the entry is a 
function address plus arg list and represents work to be done 
later. In the top loop, the app then executes these 'posted' jobs 
later at app-scheduled low priority relative to other activities 
and all handling of io and timer events, when it has nothing else 
to do, by simply calling through the function pointer in a post 
queue entry. So it's a bit like setting a timer for 0 ms, passing 
a callback function. Terminology - A DFC or lazy, late execution 
might be other terms. I'm wondering if using the garbage 
collector well might fit into this familiar pattern? That fair? 
And actually even help peformance for me if I'm lucky?


Cpu instructions exposed

2017-08-28 Thread Cecil Ward via Digitalmars-d-learn
I have written a few zero-overhead (fully inlining) D wrappers 
around certain new x64 instructions as an exercise to help me 
learn D and get used to GDC asm. I've also written D replacements 
for older processors. They are templated functions with 
customised variants supporting a variety of different word-widths.


1. Would anyone find these useful? Bet I'm inventing the wheel? 
(But still a good learning task for me.)


2. How best to get them reviewed for correct D-style and

3. how to package them up, expose them? They need to be usable by 
the caller in such a was as they get fully directly inlined with 
no subroutine calls or arg passing adaptation overhead so as to 
get the desired full 100% performance. For example a call with a 
literal constant argument should continue to mean an immediate 
operand in the generated code, which happens nicely currently in 
my testbeds. So I don't know, the user needs to see the lib fn 
_source_ or some equivalent GDC cleverness. (Like entire thing in 
a .h file. Yes, I know, I know. :-) )


4. I would like to do the same for LDC, unfortunately the asm 
system is rather different from GDC. I don't know if there is 
anything clever I can do to try to avoid duplication of effort / 
totally split sources and double maintenance? (Desperation? 
Preprocess the D sources with an external tool if all else fails! 
Yuck. Don't have one at hand right now anyway.)


Is there any way I could get D to actually generate some D code 
to help with that?


I have seen some pretty mind-blowing stuff in D using mixin or 
something - looks fantastic, just like the power of our old 
friends the evil unconstrained C macros that can generate random 
garbage C source text without limit, but in D it's done right so 
the D source can actually be parsed properly, no two languages 
fighting. I recall using this kind of source generation for 
dealing with lots of different operator-overloading routines that 
all follow a similar pattern. Can't think where else. I don't 
know what is available and what the limits of various techniques 
are. I'm wondering if I could get D to internally generate 
GDC-specific or LDC-specific source code strings - the two asm 
frameworks are syntactically different iirc - starting from a 
friendly generic neutral format, transforming it somehow. (If 
memory serves, I think GDC uses a non-D extended syntax, very 
close to asm seen in GCC for C, for easier partial re-use of 
snippets from C sources. On the other hand LDC looks more like 
standard D with complex template expansion, but I haven't studied 
it properly.)


Any general tips to point me in the right direction, much 
appreciated.






DIPs - question about mores, etiquette and DIP1009 in particular

2017-08-30 Thread Cecil Ward via Digitalmars-d-learn
Is there a way I can simply register my vote eg about DIP 1009? 
My vote is 'no thanks'. Like the existing system, don't care 
about the alleged verbosity / room thing, and please whatever do 
not deprecate the existing syntax because I use it all over the 
place and the blocks can have complex code in them using 
statements and multiple statements.


Re: DIPs - question about mores, etiquette and DIP1009 in particular

2017-08-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 17:19:52 UTC, ketmar wrote:

it is explicitly stated in DIP that existing syntax will not be 
deprecated/removed. i guess that reading the DIP before 
expressing your opinion is the prerequisite...


Good to know. A relief.

I am full of pain drugs and missed the no-deprecation thing when 
I inadequately skimmed the proposal. RTFM as always applies. :-)


Re: DIPs - question about mores, etiquette and DIP1009 in particular

2017-08-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 30 August 2017 at 22:09:21 UTC, Mike Parker wrote:

On Wednesday, 30 August 2017 at 17:16:11 UTC, Cecil Ward wrote:

DIPs are not voted on.


Thanks for letting me know, answers my question.

Our leaders would perhaps find a simple pair of numbers to be a 
useful additional metric? Demand level, or the opposite, isn't 
always that obvious, unless you are Professor X.




Address of data that is static, be it shared or tls or __gshared or immutable on o/s

2017-09-06 Thread Cecil Ward via Digitalmars-d-learn
If someone has some static data somewhere, be it in tls or marked 
shared __gshared or immutable or combinations (whatever), and 
someone takes the address of it and pass that address to some 
other routine of mine that does not have access to the source 
code of the original definition of the object in question, then 
is it possible to just use 'the address' passed without knowing 
anything about that data? I'm assuming that the answer might also 
depend on compilers, machine architectures and operating systems?


If this kind of assumption is very ill-advised, is there anything 
written up about implementation details in different operating 
systems / compilers ?


Re: Address of data that is static, be it shared or tls or __gshared or immutable on o/s

2017-09-10 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 6 September 2017 at 15:55:35 UTC, Ali Çehreli wrote:

On 09/06/2017 08:27 AM, Cecil Ward wrote:
> If someone has some static data somewhere, be it in tls or
marked shared
> __gshared or immutable or combinations (whatever), and
someone takes the
> address of it and pass that address to some other routine of
mine that
> does not have access to the source code of the original
definition of
> the object in question, then is it possible to just use 'the
address'
> passed without knowing anything about that data? I'm assuming
that the
> answer might also depend on compilers, machine architectures
and
> operating systems?
>
> If this kind of assumption is very ill-advised, is there
anything
> written up about implementation details in different
operating systems /
> compilers ?

Yes, they are all valid operations. Further, the object need 
not be a static one; you can do the same with any object even 
it's on the stack. However,


- The object must remain alive whenever the other routine uses 
it. This precludes the case of the object being on the stack 
and the other routine saving it for later use. When that later 
use happens, there is no object any more. (An exception: The 
object may be kept alive by a closure; so even that case is 
valid.)


- Remember that in D data is thread-local by default; e.g. a 
module variable will appear to be on the same address to all 
threads but each thread will have its own copy. So, if the data 
is going to be used in another thread, it must be defined as 
'shared'. Otherwise, although the code will look like it's 
working, different threads will be accessing different data. 
(Sometimes this is exactly what is desired but not what you're 
looking for.) (Fortunately, many high-level thread operations 
like the ones in std.concurrency will not let you share data 
unless it's 'shared'.)


Ali


Ali, I have worked on operating systems' development in r+d. My 
definitions of terms are hopefully the same as yours. If we refer 
to two threads, if they both belong to the same process, then 
they share a common address space, by my definition of the terms 
'thread' and 'process'. I use thread to mean basically a stack, 
plus register set, a cpu execution context, but has nothing to do 
with virtual memory spaces or o/s ownership of resources, the one 
exception being a tls space, which by definition is 
one-per-thread. A process is one or more threads plus an address 
space and a set of all the resources owned by the process 
according to the o/s. I'm just saying this so you know how I'm 
used to approving this.


Tls could I suppose either be dealt with by having allocated 
regions within a common address space that are all visible to one 
another. Objects inside a tls could (1) be referenced by absolute 
virtual addresses that are meaningful to all the threads in the 
process, but not meaningful to (threads belong to) other 
processes. (By definition of 'process'.) or (2) be referenced 
most often by section-offsets, relative addresses from the start 
of a tls section, which constantly have to be made usable by 
having the tls base virtual address added to them before they can 
be dereferenced adding a big runtime cost and making tls very bad 
news. I have worked on a system like (2). But even in (2) an 
address of a type-2 tls object can still be converted to a 
readily usable absolute virtual address and used by any thread in 
the process with zero overhead. A third option though could be to 
use processor segmentation, so tls objects have to (3a) be 
dereferenced using a segment prefixed operation, and then it's 
impossible to just have a single dereference operation such as 
star without knowing whether to use the segment prefix or not. 
But if it is again possible to use forbidden or official 
knowledge to convert the segmented form into a process-wide 
meaningful straight address (as in 8086 20-bit addresses) then we 
could term this 3a addressing. If this is not possible because vm 
hardware translation is in use then I will term this 3b. In 3a I 
am going to assume that vm hardware is used merely to provide 
relocation, address offsetting, so the use of a segmentation 
prefix basically merely adds a per-thread fixed offset to the 
virtual address and if you could discover that offset then you 
don't need to bother with the segment prefix. In 3b, vm hardware 
maps virtual addresses to a set of per-tls pages using 
who-knows-what mechanism, anyway something that apps cannot just 
bypass using forbidden knowledge to generate a single 
process-wide virtual address. This means that 3b threads are 
probably breaking my definition of thread vs process, although 
they threads of one process do also have a common address space 
and they share resources.


I don't know what d's assumptions if any are. I have very briefly 
looked at some code generated by GDC and LDC for Linux x64. It 
seems to me that these are 3a systems, optimised strongly enough 
by the compilers to

Compiler magic for preventing memory access re-ordering _by the compiler_ (keywords: memory model, compiler optimisations, memory order)

2017-11-05 Thread Cecil Ward via Digitalmars-d-learn
I have to apologise in advance for a truly dumb question, so 
please be kind.


Is there a magic visible sign (or even one needed) in the D 
language that tells D _compilers_ not to move certain types of 
memory load / store operations forwards or backwards relative to 
other operations when optimising the code so that the order in 
the actual generated code varies from the source code order?


I see the various routines available in the runtime library that 
can generate various sorts of special instructions on CPU x, 
hardware fences/barriers etc. That's not what I'm asking about 
tho. I'm just wondering about how the compilers know how much 
freedom they are allowed in moving stuff forwards/backwards or 
even deleting stupid wasteful memory operations altogether, and 
whether there are any special things that a compiler writer needs 
to spot as being magic in D source code.


If the answer is 'no'/'none', I suppose it could be in part down 
to the fact that the _implementation_ of certain D features by 
compilers make use of various compiler-specific non-D magic 
facilities that a compiler already has anyway due to its modern 
C-implementation heritage? But I don't feel that I've answered my 
question in this way, if a compiler is generally free to re-order 
certain statements or external calls past other external calls or 
special statements. That's a general statement of my ignorance 
about the limits of compilers’ freedom in optimising code, and 
something I urgently need to correct. :-) A completely general 
question, which I should have found an answer to first. (Again, 
please be nice to a poor fool.)


This could be a non-question for all I know, so do forgive my 
ignorance. If calls to certain types of _routines_ whose content 
is not know can not be re-ordered either simply (a) because their 
effects are unknown, or (b) because 'volatile' type declarations 
are used in the implementation, is that merely how things happen 
to work? One further dumb question relating to this: if this is 
meaningful and the answer is case (a) could inlining stuff copied 
out of the runtime library into your own routines then wreck the 
safety, and could LTO-type highly clever whole-program 
optimisation undo safety similarly?


Returning constant / literal struct value (pod)

2018-03-09 Thread Cecil Ward via Digitalmars-d-learn
Can we return a literal struct value straight from a return 
statement ?


ie something like
mystruct_t myfunc()
{ // ... blah
return { field1: val1, field2: val2; };
}
assuming that the return type is defined suitably, and the struct 
is just a C struct, plain-old-data (ie not a C++-like class).


I've had to set up a throwaway const item, initialised, and then 
had to return that.


Function argument that is a pointer to memory which the function is not allowed to modify, as in C const

2018-03-14 Thread Cecil Ward via Digitalmars-d-learn

say in C I have a function with a pointer argument
foo( const sometype_t * p )

I have asked about this D nightmare before. Using the same 
pattern in D or the in argument qualifier as far as I can see the 
value of the pointer is then itself effectively locked made 
constant. Without dangerous and ugly casts you are stuck.


q1. If you want a pointer to memory that is not to be modified 
then you can't walk the pointer through that memory.  So what are 
my options? I need a pointer that I can increment. (I could avoid 
the whole issue by using an index instead, but that seems to be 
giving in to madness.)


It seems to me that this is the worst thing I have seen about D. 
Perhaps trying to make pointers unusable is a surreptious 
strategt]y for encouraging designers to phase them out. Making 
code unsafe just to get out of this nightmare (by casting or 
giving up and dropping important const protection) is not the way.


q2. If you want a pointer to modifiable memory but wish to ensure 
that the value of that address stays fixed, stays where it's put, 
then what on earth do you do. What are my options?


Is there any way at all to campaign for a change to this 
craziness? I doubt this is a democracy. It's also rather more 
than a bit late.


q3. The in keyword seems to be mixed up concerning the 
distinction between modifiable arguments and modifiable memory. 
Is there any way of making in usable for the purposes of 
documenting the calling convention, showin which arguments are 
inputs only, which are outputs and which are modified - 
read-modified-returned?


Apologies for my lack for my lack of familiarity with the 
possible ways out of this.


q4. If my understanding is correct, it seems difficult to create 
a non const copy of (an address that is fixed) either; that is, 
making a modifiable copy of an address, one which can be 
incremented, moved upwards starting from a locked base address. 
It seems that declaring a pointer argument with const or even 
using the keyword in triggers this problem, the latter being 
particularly nightmarish because I would want in to mean that 
that argument (the address, which is what I am declaring) is 
merely an input-only parameter to the routine, or alternatively a 
locked /fixed address value which stay s put, and nothing.


I'm interested in the cleanest safest techniques for digging 
myself out of this while always preserving const correctness, 
preventing possibility of writing to memory and preventing evil 
type changes where pointers end up pointing to some different 
kind of objects because if evil casting. I really don't want to 
use casts that have to much power, where they could allow 
overrides to any kind of bugs in or even create a new bug, 
including cases when things break because of duplication of types 
so later changes of types cause a bug because kludge contain 
duplicate type specifiers that do not get updated.


There probably is a tool somewhere to safely create a modifiable 
object based on a const object but I'm not sure where to look.


Any wise guidance appreciated mucky.


Networking library

2018-03-14 Thread Cecil Ward via Digitalmars-d-learn
Can anyone point me in the direction of a library that provides 
very very lightweight (minimum overhead) asynchronous i/o 
routines for - shopping list


1. sending and receiving IPv4 / IPv6 packets,
2. sending receiving ICMP and
3, handling incoming outgoing TCP connections and
4. handling SCTP connections.

Secondingly I am in the market for a library that handles the 
sending and receiving of straight ethernet packets. Also doing 
ARP / NDP too.


Rules of the beauty contest: Some abstraction of asynchronous i/o 
with asynchronous events, but the main priority is being very 
very lean and low-level, with top time-performance. If it comes 
to a beauty contest, this judge I would prefer something C-style 
as I don't speak C++, have yet to drink the mindless class 
bullshit koolaid. Since my background is VAX/VMS asynchronous io 
an asynchronous model with optional callbacks as in VMS or Win NT 
events will win the beauty parade. Operating systems? Cross-o/s 
portability- unsure. Not interested in solutions that are 
synchronous-io-only and so require your code to be split up into 
multiple threads just to get around the problems caused by 
synchronous (‘blocking’ some call it) io calls. Requiring threads 
is a rule-out / show stopper unless I could easily hide such a 
thing, but that doesn't sound feasible.


Any suggestions gratefully received.


Re: Networking library

2018-03-14 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 15 March 2018 at 00:06:49 UTC, Cecil Ward wrote:
Can anyone point me in the direction of a library that provides 
very very lightweight (minimum overhead) asynchronous i/o 
routines for - shopping list


[...]


Actually I realise that if I could simply write a wrapper pretty 
easily, with suitable help, then C libraries could be included in 
the list of candidates, but only if I can get the necessary help 
in writing a D-toC & C-to-D safe wafer-thin wrapper layer.


Re: Function argument that is a pointer to memory which the function is not allowed to modify, as in C const

2018-03-15 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 14 March 2018 at 22:23:47 UTC, Cecil Ward wrote:

say in C I have a function with a pointer argument
foo( const sometype_t * p )

[...]



That's the secret - I didn't know about the const (T) * thing - I 
would never have discovered that ! Many thanks, the missing piece 
to the puzzle.


Many generous replies, thanks to all for their extremely helpful 
contributions. There is a wealth of precious explanation in them, 
and apologies for not thanking the contributors individually.


Re: Efficient way to pass struct as parameter

2018-03-15 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:
I am creating Vector3 structure. I use struct to avoid GC. 
However, struct will be copied when passed as parameter to 
function



struct Ray {
Vector3f origin;
Vector3f dir;

@nogc @system
this(Vector3f *origin, Vector3f *dir) {
this.origin = *origin;
this.dir = *dir;
}
}

How can I pass struct more efficiently?


This isn't a question for you. it's a question for the compiler, 
let the compiler do its thing. Stick in a -O3 if you are using 
GCC or LDC and build in release more not debug mode. Make sure 
that the compiler can see the source code of the implementation 
of the constructor wherever it is used and it should just be 
inclined away to nonexistence. Your constructor should not even 
exist, if it is then you are looking at a false picture or a 
mistake where optimisation has been turned off for the sake of 
easy source-level debugging.


Post up the assembler language output for a routine where this 
code is used in some critical situation, and then we can help 
make sure that the code _generation_ is optimal.


I reiterate, unless something is badly wrong or you are seeing a 
red herring, no 'call' to the constructor code should even exist 
in the cases where it is actually 'called'. You may well see a 
useless copy of the constructor code because the compilers seem 
to generate such even though it is never called ans so is a waste 
of space. The compiler will analyse the constructor's 
instructions and just copy-and-paste them as assignment 
statements with that then getting thoroughly optimised down into 
something which may just be a memory write or a register-register 
copy that costs zero.


If you post up snippets of generated asm then U will be delighted 
to take a look.


Re: Efficient way to pass struct as parameter

2018-03-15 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 15 March 2018 at 23:14:14 UTC, Cecil Ward wrote:

On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:

[...]


U


or even 'I' will be delighted to take a look.


Re: Efficient way to pass struct as parameter

2018-03-15 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 15 March 2018 at 23:15:47 UTC, Cecil Ward wrote:

On Thursday, 15 March 2018 at 23:14:14 UTC, Cecil Ward wrote:

On Tuesday, 2 January 2018 at 18:21:13 UTC, Tim Hsu wrote:

[...]


U


or even 'I' will be delighted to take a look.


Also link time optimisation and whole program optimisation might 
be your friends if you are having problems because module 
boundaries mean that the compiler cannot expand the source code 
of the constructor implementation to inline it and fully optimise 
it away to nothing.


You certainly should have no problems if the code that uses the 
struct can see the struct definition's actual source text 
directly.




remote execute program

2018-03-22 Thread Cecil Ward via Digitalmars-d-learn
I am wanting to write a short program (on a ‘server’ you could 
say) that takes a command, runs it (as on the command line, so an 
executable with arguments or a shell command) and returns a 
3-tuple with an int for the return code, plus the textual outputs 
that it generates to stdout and stderr. I can see a number of 
suitable routines in the D runtime libraries, which are already 
D-ified to save me a some trouble mindlessly converting code from 
C.


Where I could do with some help is as follows: I'm needing to 
send the commands to a remote box using http has to be used 
because the local-end program (on an iPad) that I have to 
interfacing to can only speak http/https, and can not handle just 
a straight eg TCP connection. Despite the overheads from using 
http, if I can employ gzip compression on the link then that will 
be a big gain.


Could anyone give me some general pointers for where to look?

The server box is a linux machine. I'm a very experienced 
professional C programmer but amazingly have never done anything 
with *nix in general or http-related C libraries.



I asked a question in this forum earlier about general low-level 
networking, but now this requirement has come up that mandates 
the use of very simple http and needs only synchronous 
operations. The impressive framework that is vibe.d has already 
been mentioned, but the amount of reading matter is rather 
daunting.


A simple D example of an http transaction would be very helpful.






Re: remote execute program

2018-03-23 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 23 March 2018 at 07:57:33 UTC, Kagamin wrote:
You can just read the whole request into a buffer and parse it 
there.


Agreed.




Re: remote execute program

2018-03-23 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 23 March 2018 at 01:23:56 UTC, Cecil Ward wrote:
I am wanting to write a short program (on a ‘server’ you could 
say) that takes a command, runs it (as on the command line, so 
an executable with arguments or a shell command) and returns a 
3-tuple with an int for the return code, plus the textual 
outputs that it generates to stdout and stderr. I can see a 
number of suitable routines in the D runtime libraries, which 
are already D-ified to save me a some trouble mindlessly 
converting code from C.


Where I could do with some help is as follows: I'm needing to 
send the commands to a remote box using http has to be used 
because the local-end program (on an iPad) that I have to 
interfacing to can only speak http/https, and can not handle 
just a straight eg TCP connection. Despite the overheads from 
using http, if I can employ gzip compression on the link then 
that will be a big gain.


Could anyone give me some general pointers for where to look?

The server box is a linux machine. I'm a very experienced 
professional C programmer but amazingly have never done 
anything with *nix in general or http-related C libraries.



I asked a question in this forum earlier about general 
low-level networking, but now this requirement has come up that 
mandates the use of very simple http and needs only synchronous 
operations. The impressive framework that is vibe.d has already 
been mentioned, but the amount of reading matter is rather 
daunting.


A simple D example of an http transaction would be very helpful.


It's not really a D question, in a sense, it's just that I am out 
of my depth. And wrapping fat C libraries, particularly 
converting .h files is something that I don't have any experience 
of, so something ready-cooked in D would b good.


What library routines are available - or do I have to start 
wading through the vastness of vibe.d?


Link-time optimisation (LTO)

2018-03-30 Thread Cecil Ward via Digitalmars-d-learn
Say that I use say GDC or LDC. I want to declare a routine as 
public in one compilation unit (.d src file) and be able to 
access it from other compilation units.


Do I simply declare the routine with the word keyword public 
before the usual declaration?


Or maybe that is the default, like not using the keyword static 
with function declarations in C?


My principal question: If I successfully do this, with GCC or 
LDC, will I be able to get the code for the externally defined 
short routine expanded inline and fully integrated into the 
generated code that corresponds to the calling source code? (So 
no ‘call’ instruction is even found.)


Alignment of struct containing SIMD field - GDC

2017-02-28 Thread Cecil Ward via Digitalmars-d-learn

struct vec_struct {
alias field this;
bool b;
int8 field;
}

In this code when you look at the generated x64 code output by 
GDC it seems to be doing a nice job, because it has got the 
offset right for the 256-bit YMM 'field' correct.


Does D automatically propagate the alignment restrictions on the 
field to the allocation of static structs or structs on the stack?


In this case:

struct vec_struct {
bool b2;
struct {
alias field this;
bool b;
int8 field;
}
}
it appears that the offset to 'field' is no longer aligned 
correctly - offset is 40 bytes in GDC. I don't suppose the 
compiler will use solely unaligned instructions? In any event, I 
could take the address of field and then pass that to someone 
expecting to pick up something with guaranteed correct alignment, 
if I have understood the D docs.


Please don't bite. I'm both new to D and I hope I have understood 
the x86 SIMD instructions' docs. (Very experienced professional 
asm and C programmer, but v out-of-date.)


Noob q: I notice that the GDC opcodes look a bit odd, for example 
the compiler generates a 256-bit unaligned fetch followed by an 
aligned binary operation (I think), eg a movdqu followed by a 
vpaddd r, ymm ptr blah - is the latter aligned-only? Apologies if 
I have got this wrong, need to read up. Would someone 
sanity-check me?


Re: Alignment of struct containing SIMD field - GDC

2017-03-01 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:

On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:

On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:


Simple test case would be:

struct vec_struct {
bool b2;
struct {
bool b;
int8 field;
}
}

static assert(vec_struct.b.offsetof == 32);
static assert(vec_struct.field.offsetof == 64);


With explicit align(32), it works:
https://godbolt.org/g/3GjOHW

- Johan


Well obviously, because it adheres to explicit alignment.  The 
compiler just has the wrong idea of how default alignment 
should work.


Raised bug here, and I'm raising a PR now also. 
https://issues.dlang.org/show_bug.cgi?id=17237


Thanks for your help Iain. And many thanks btw for all the 
general good work which is very much appreciated by this 
particular geriatric asm programmer.


I checked the case of XMM alignment, and it's fine.

I presume D does not yet support 512-bit zmm vector objects? (I 
have seen GDC doing a nice job generating auto-vectorised AVX512 
code though - thanks.) The same bug would presumably bite again 
in that case otherwise?


Re: Alignment of struct containing SIMD field - GDC

2017-03-01 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:

On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:

On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:


Simple test case would be:

struct vec_struct {
bool b2;
struct {
bool b;
int8 field;
}
}

static assert(vec_struct.b.offsetof == 32);
static assert(vec_struct.field.offsetof == 64);


With explicit align(32), it works:
https://godbolt.org/g/3GjOHW

- Johan


Well obviously, because it adheres to explicit alignment.  The 
compiler just has the wrong idea of how default alignment 
should work.


Raised bug here, and I'm raising a PR now also. 
https://issues.dlang.org/show_bug.cgi?id=17237


In a dream world where engineers have nothing better to do, it 
would of course be better to effectively delete the inner 
anonymous struct so that the two bools could be packed together 
adjacently. I presume that that is theoretically ok? In contrast, 
if the sub-struct were named, you could presumably take the 
address of the entire sub-struct, so the space-inefficient offset 
to it is something you are just stuck with of course.


A noob question: is it illegal to reorder the fields in a struct? 
(e.g. so as to optimise packing as far as correct alignment 
allows) - (C compatibility? Would perhaps need to be an _option_?)


Re: Alignment of struct containing SIMD field - GDC

2017-03-02 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 1 March 2017 at 22:15:59 UTC, Iain Buclaw wrote:

On Wednesday, 1 March 2017 at 19:09:24 UTC, Johan Engelen wrote:

On Wednesday, 1 March 2017 at 18:34:16 UTC, Iain Buclaw wrote:


Simple test case would be:

struct vec_struct {
bool b2;
struct {
bool b;
int8 field;
}
}

static assert(vec_struct.b.offsetof == 32);
static assert(vec_struct.field.offsetof == 64);


With explicit align(32), it works:
https://godbolt.org/g/3GjOHW

- Johan


Well obviously, because it adheres to explicit alignment.  The 
compiler just has the wrong idea of how default alignment 
should work.


Raised bug here, and I'm raising a PR now also. 
https://issues.dlang.org/show_bug.cgi?id=17237


Iain, this of course is present in my version of LDC too. (I 
checked.) You couldn't poke David Nadlinger or whoever for me?


Calling a C function whose name is a D reserved word or keyword

2020-07-06 Thread Cecil Ward via Digitalmars-d-learn
Is there a special mechanism in D for handling this problem, 
where an existing C function might be a name that is reserved in 
D? Of course I could write a wrapper function in C and call that.


Re: Calling a C function whose name is a D reserved word or keyword

2020-07-11 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 6 July 2020 at 23:40:23 UTC, rikki cattermole wrote:

https://dlang.org/spec/pragma.html#mangle

pragma(mangle, "body")
extern(C) void body_func();


Thanks, that’s excellent


Question about publishing a useful function I have written

2020-07-14 Thread Cecil Ward via Digitalmars-d-learn
I have written something which may or may not be novel and I’m 
wondering about how to distribute it to as many users as 
possible, hoping others will find it useful. What’s the best way 
to publish a D routine ?


It is called
void assume( bool condition ) nothrow nogc safe

for example:
assume( x < 100 );
or
assume( y != 0 );

It generates no code at all, but t does tell the gdc compiler 
that the given condition is true and so later code generation may 
assume that truth in all code generation. So for example, given 
the assumes above,

if ( x==200)
is false and no code is generated for the if-true basic block.

It might look a bit like assert but it isn’t the same thing. I 
think assert is disabled in full release build and is only there 
in debug mode, is that correct? Also assert generates code in 
that it calls panic or hits a ud2 or whatever, whereas assume is 
also zero code.


Does anyone know if this has already been published by someone 
else?


Unfortunately at the moment it only works with gdc as it relies 
on functions that are gdc-specific for its implementation. 
However I could use conditional compilation to simply set up a 
null implementation for other compilers.


I’d like to get it implemented with ldc if I can.


If anyone would like to give assume a try with gdc, then shout 
and I’ll try and find some way of getting it to you easily.


Re: Question about publishing a useful function I have written

2020-07-15 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 23:10:28 UTC, Max Haughton wrote:

On Tuesday, 14 July 2020 at 21:58:49 UTC, Cecil Ward wrote:
I have written something which may or may not be novel and I’m 
wondering about how to distribute it to as many users as 
possible, hoping others will find it useful. What’s the best 
way to publish a D routine ?


[...]


GitHub is the best place to publish code. Does GDC actually use 
the optimization? I tried something like that before but I 
couldn't seem to get it to work properly.


On Tuesday, 14
]

I just tried an experiment. It seems that in release mode 
assert()s are realised as absolutely nothing at all, and so the 
_conditions_ in the asserts are not declared. So later generated 
code does not have the benefit of knowledge of asserted truth 
conditions in release mode. So in release mode, without these 
truth conditions being established, the code generated (apart 
from the asserts’ code) can be _worse than in debug mode_, which 
seems bizarre, but it’s true.


for example
assert( x < 100 );
…
if ( x==200 )  // <— evaluates to false _at compile time_
 {
 // no code generated for this block in debug mode,
 // but is generated in release mode
 }
…
if ( x < 100 ) // <— no code generated for if-test as cond == 
true at compile-time


Re: Question about publishing a useful function I have written

2020-07-15 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 15 July 2020 at 02:25:42 UTC, 9il wrote:

On Tuesday, 14 July 2020 at 21:58:49 UTC, Cecil Ward wrote:



Does anyone know if this has already been published by someone 
else?




https://github.com/libmir/mir-core/blob/master/source/mir/utility.d#L29

We test LDC and DMC. CI needs an update to be actually tested 
with GDC.


Brilliant. Many thanks.


Forcing inline functions (again) - groan

2020-07-15 Thread Cecil Ward via Digitalmars-d-learn

I recently noticed
pragma(inline, true)
which looks extremely useful. A couple of questions :

1. Is this cross-compiler compatible?

2. Can I declare a function in one module and have it _inlined_ 
in another module at the call site?


I’m looking to write functions that expand to approx one or even 
zero machine instructions and having the overhead of a function 
call would be disastrous; in some cases would make it pointless 
having the function due to the slowdown.


Templates and SIMD - examining types

2020-07-22 Thread Cecil Ward via Digitalmars-d-learn
I am using SIMD and I have a case in a template where I am being 
passed an argument that is a pointer to a 128-bit chunk of either 
16 bytes or 8 uwords but I don’t know which? What’s the best way 
to discover this at compile time - using the ‘is’ operator ? I 
forget for the moment. It will only ever be either a ubyte16 or a 
ushort8 (if those are the correct type names)? I’ll exclude other 
possibilities with an if qualifier on the template (somehow).


I need to then work out what is the size of the internal units 
within the 128-bit value, size in bytes,1 or 2, at compile time.


Re: Templates and SIMD - examining types

2020-07-27 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 22 July 2020 at 22:21:47 UTC, Dennis wrote:

On Wednesday, 22 July 2020 at 21:58:16 UTC, Cecil Ward wrote:
I need to then work out what is the size of the internal units 
within the 128-bit value, size in bytes,1 or 2, at compile 
time.


You can use the .sizeof property on the type.

```
import core.simd;
void main() {
ubyte16 a;
ushort8 b;
pragma(msg, a.sizeof);
pragma(msg, b.sizeof);
pragma(msg, a[0].sizeof);
pragma(msg, b[0].sizeof);
pragma(msg, typeof(a[0]));
pragma(msg, typeof(b[0]));
}
```

16LU
16LU
1LU
2LU
ubyte
ushort
Brilliant. I am sooo stupid, I forgot you can access SIMD 
variables like normal arrays. Thank you for waking me up again :-)




Strong typing and physical units

2020-07-27 Thread Cecil Ward via Digitalmars-d-learn
I found an earlier post somewhere about work someone has done on 
physical units such as kg, volts and so forth.


It would be very good to catch bugs such as

volts_t v = input_current;

But that isn’t nearly enough. With strong typing where we can 
create arbitrary subtypes that are chosen to be incompatible 
because they are semantically incompatible in assignment, 
equality, addition and various other operations, we can catch a 
lot more bugs.


 point1.x = point2.y;

the above is illegal but we need a way to get the underlying 
value so we can handle rotation by angle of 90 deg or whatever. 
These two variables have the same units; their unit is pixels but 
they cond have a real SI physical unit of length in metres say. 
Even when they are of the same physical units type they need to 
be made incompatible to prevent y coordinates from getting mixed 
up with x coordinates by mistake.


also

point1.x = width; // illegal

and

point1.x = height; // even worse

Arbitrary sub typing would help here but would need accompanying 
tools to make it usable, the ‘get underlying value’ thing 
mentioned earlier might not be the only one, I’m not sure.


Any thoughts ?

—
I tried to do something with wrapping a double say in a 
(templated) struct with just one field value_ in it and an alias 
value_ this; but as a miserable D learner, I soon got lost.


for some reason when using alias this as above, I can do 
assignments to my struct, but I cannot initialise it using the 
alias this simplification mechanism. I’m not sure why. I’m 
assuming I need an appropriate trivial constructor but why 
doesn’t this get sorted out for you automatically when you’re 
using alias this? That would seem to be logical, no? Asking for 
too much - greedy :-)



Cecil Ward.


Lack of asm volatile qualifier (explicitly) again.

2020-07-28 Thread Cecil Ward via Digitalmars-d-learn
I read recently that all asm in D is regarded as ‘volatile’ in 
the GCC sense, which I take to mean that it is assume to 
potentially have side effects, and so cannot be optimised away to 
nothing by the compiler despite the lack of any outputs.


I would like to be able to either use the asm volatile qualifier 
now and have it do absolutely nothing or else have an alternative 
way of expressing the licence for optimisation allowed by the 
designer. If it is now way too late to declare that suddenly the 
_lack_ of volatile means that the compiler can go 
optimisation-crazy, then we need some alternative 
‘is_optimisable’ keyword.


Even if we think that we need an ‘is-optimisable’ qualifier, then 
I would still like to be able to include the asm volatile 
qualifier or similar just to document the designer’s intent in 
cases where we genuinely do have a non-obvious side effect in the 
asm.


What do others think? If others agree, how could a very small DIP 
be set in motion ?


That would mean just adding one or two new keywords for the asm 
qualifier(s), which do precisely nothing at present.


If GCC and LDC were willing to start optimising at some point 
then it would be a matter of doing what the sibling C compilers 
do with volatile and non-volatile.


Re: Strong typing and physical units

2020-07-28 Thread Cecil Ward via Digitalmars-d-learn
On Tuesday, 28 July 2020 at 07:16:53 UTC, Petar Kirov 
[ZombineDev] wrote:

On Tuesday, 28 July 2020 at 04:40:33 UTC, Cecil Ward wrote:

[snip]


By the way, I found 2 implementations of unit of measurement in 
D:

https://code.dlang.org/packages/units-d
https://code.dlang.org/packages/quantities


Thank you Peter! Very helpful.

Do you guys have any thoughts also about the strong typing idea?


Re: Strong typing and physical units

2020-07-28 Thread Cecil Ward via Digitalmars-d-learn
Of course, in C I used to do something like strong typing with an 
opaque type achieved by using something like typedef struct 
_something {} * type1; and then I had to do casting to get back 
the real type, which was unchecked but it did prevent the user 
from mixing up the types type1 and type2 say as they weren’t 
assignment compatible.


I would really like strong typing to be a built in feature. Would 
anyone else support this?


Re: Strong typing and physical units

2020-07-28 Thread Cecil Ward via Digitalmars-d-learn
I just remembered: another favourite bug of mine would be mixing 
up indices, using an index with the wrong array, an index to a 
different array entirely. they’re all just a nightmare load of 
meaningless ints or uints or hopefully size_t’s.


Re: Lack of asm volatile qualifier (explicitly) again.

2020-07-31 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 30 July 2020 at 07:05:39 UTC, Iain Buclaw wrote:

On Tuesday, 28 July 2020 at 06:57:36 UTC, Cecil Ward wrote:
I read recently that all asm in D is regarded as ‘volatile’ in 
the GCC sense, which I take to mean that it is assume to 
potentially have side effects, and so cannot be optimised away 
to nothing by the compiler despite the lack of any outputs.


I would like to be able to either use the asm volatile 
qualifier now and have it do absolutely nothing or else have 
an alternative way of expressing the licence for optimisation 
allowed by the designer. If it is now way too late to declare 
that suddenly the _lack_ of volatile means that the compiler 
can go optimisation-crazy, then we need some alternative 
‘is_optimisable’ keyword.




Until recently the absence of the pure keyword implied volatile 
in gdc. I do plan to re-add it, either only in release mode, or 
when warnings are added for the following:


---
asm pure {
  "get flags" : "=r" (x);
}
assert(x == 1);

asm {
  "set flags" : : "r" (x + 1);
}

asm pure {
  "get flags" : "=r" (x);
}
assert(x == 2);
---

The second 'get flags' would be removed if optimizing as it is 
both identical to the first statement, and not clear to the 
compiler that there is a dependency between the setter and 
getter statements.


Just highlighting one example that might be surprising if you 
weren't thinking that optimizing mean that as well.


Ah. I wasn’t thinking about pure, although I do use it everywhere 
I can as a matter of course. The absence of something doesn’t hit 
you in the eye as an expression of the programmer’s intent I 
suppose, absence of pure just could mean the author forgot to put 
it in. I see your point though. The value of volatile I saw as in 
documentation.


Re: Lack of asm volatile qualifier (explicitly) again.

2020-08-02 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 1 August 2020 at 19:23:00 UTC, Iain Buclaw wrote:

On Saturday, 1 August 2020 at 02:36:41 UTC, Cecil Ward wrote:

On Thursday, 30 July 2020 at 07:05:39 UTC, Iain Buclaw wrote:

[...]


Ah. I wasn’t thinking about pure, although I do use it 
everywhere I can as a matter of course. The absence of 
something doesn’t hit you in the eye as an expression of the 
programmer’s intent I suppose, absence of pure just could mean 
the author forgot to put it in. I see your point though. The 
value of volatile I saw as in documentation.


When the baseline for asm is volatile, I don't think it's 
entirely surprising to consider pure as a cancellation of that 
- afterall, if it truly is side-effect free, then it's fine for 
the compiler to remove the statement block.


We are in agreement.


Question about UDAs

2020-08-02 Thread Cecil Ward via Digitalmars-d-learn
When practically speaking would you use UDAs? A real-world 
use-case? I’ve seen them in use already for core language 
features instead of keywords like "pure", and I suppose this 
choice keeps the number of keywords down and the result is 
perhaps easier to extend. The motivation for these usages is 
clear but I don’t understand how I might use them in my own code. 
Ali Çehreli’s book mentions them briefly with an example but that 
doesn’t seem to qualify as a realistic use-case.


Types of lambda args

2020-08-16 Thread Cecil Ward via Digitalmars-d-learn
In a lambda, how do we know what types the arguments are? In 
something like

(x) => x * x

- there I just don’t get it at all. Can you write
(uint x) => x * x

I’m lost.

Cecil Ward.


Re: Types of lambda args

2020-08-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 17 August 2020 at 04:30:08 UTC, H. S. Teoh wrote:
On Mon, Aug 17, 2020 at 12:20:24AM +, Cecil Ward via 
Digitalmars-d-learn wrote:
In a lambda, how do we know what types the arguments are? In 
something

like
(x) => x * x


It's implemented as a template, whose argument types are 
inferred based on usage context.




- there I just don’t get it at all. Can you write
(uint x) => x * x


Of course you can.



I’m lost.

[...]

If you're ever unsure of what the inferred type(s) are, you can 
do replace the lambda with something like this:


(x) { pragma(msg, typeof(x)); return x*x }

which will print out the inferred type when the compiler 
instantiates the lambda.



T


Ah! That’s the vital missing piece - I didn’t realise it was like 
a template - I just thought it was an ordinary plain anonymous 
function, not a generic. All makes sense now.





Named parameters in function call

2020-09-08 Thread Cecil Ward via Digitalmars-d-learn

I can’t remember, do Ada or Modula2 have something like
 myfunc( x => 100, y => 200, color => blue )[1]
which has named parameters that can be passed in any order.

Does D have anything like this? If not, would anyone support a 
development like the above [1] ?



If D does not have this, I am wondering about how to write such a 
thing but the cure might very very easily be worse than the 
disease. I have little clue here. I have seen a hack for C 
(written by RevK) that involves assignments to fields in a struct 
and the struct is then passed to a function.


Something like
myfunc( { field2: 20, field1: 10, fieldstr : "a string" } )   
 [2]
and preprocessor trickery was used to get rid of the unsightly { 
} by making a macro call to a wrapper macro that takes variadic 
... arguments.




Re: Named parameters in function call

2020-09-08 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 8 September 2020 at 09:40:11 UTC, Andre Pany wrote:

On Tuesday, 8 September 2020 at 07:43:05 UTC, Cecil Ward wrote:

I can’t remember, do Ada or Modula2 have something like
 myfunc( x => 100, y => 200, color => blue )[1]
which has named parameters that can be passed in any order.

[...]


I hope we have it this year or next year, as we have this DIP
https://www.github.com/dlang/DIPs/tree/master/DIPs%2FDIP1030.md

Kind regards
Andre


I wonder if there is any way in which we could combine this with 
strong typing of some sort (how?) to detect errors such as

int xcoord;
int ycoord;

myfunc( x : ycoord, y : xcoord, color : blue )[3]

where the arguments are the wrong way around. Would have to 
change the types of the xcoord and ycoord variables somehow, 
something I have asked about earlier.


Range checked assignment

2020-09-08 Thread Cecil Ward via Digitalmars-d-learn

What I would like to do is (in pseudo-code) :

   declare_var my_var : int range 0..7; // i.e. 0 <= val <= 7;

my_var = 6; // ok
my_var = 8; // bang ! static assert fail or assert fail at 
runtime


my_var = 6;
my_var += 2; // bang ! value 8 is > 7

So every assignment is range-checked at either compile-time if at 
all possible or else at runtime. This includes things like += and 
initialisers of course, not just straight assignment.


I assumed I would have to create a struct type definition and 
handle various operators. How many will I have to handle? I would 
of course make it a template so I can reuse this otherwise 
horribly repetitive code.




Re: Range checked assignment

2020-09-09 Thread Cecil Ward via Digitalmars-d-learn
On Tuesday, 8 September 2020 at 16:04:29 UTC, Harry Gillanders 
wrote:

On Tuesday, 8 September 2020 at 14:18:14 UTC, Cecil Ward wrote:

[...]



If you want to define an integral-like type which is 
more-or-less interchangeable with the native integral types, 
you'll need to provide the following overloads and members:


[...]


Harry, thank you indeed for your generous help. Much appreciated.


Re: Named parameters in function call

2020-09-09 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 9 September 2020 at 11:48:28 UTC, Paul Backus wrote:

On Tuesday, 8 September 2020 at 13:28:22 UTC, Cecil Ward wrote:


I wonder if there is any way in which we could combine this 
with strong typing of some sort (how?) to detect errors such as

int xcoord;
int ycoord;

myfunc( x : ycoord, y : xcoord, color : blue )[3]

where the arguments are the wrong way around. Would have to 
change the types of the xcoord and ycoord variables somehow, 
something I have asked about earlier.


import std.typecons: Typedef;

alias XCoord = Typedef!(int, int.init, "XCoord");
alias YCoord = Typedef!(int, int.init, "YCoord");

auto myfunc(XCoord x, YCoord y) { ... }


Brilliant. Thank you Paul.


enum and const or immutable ‘variable’ whose value is known at compile time

2020-09-16 Thread Cecil Ward via Digitalmars-d-learn

A really stupid question, I fear.

If I have some kind of declaration of some ‘variable’ whose value 
is strictly known at compile time and I do one of the following 
(rough syntax)


either
   enum foo = bar;
or
   const foo = bar;
or
   immutable foo = bar;

then is there any downside to just using enum all the time?

- I don’t need to take the address of foo, in fact want to 
discourage &foo, (as I said, given that I can do so)


Is there any upside either to using enum?

I’m a bit nervous about using immutable having had bad allergic 
reactions when passing immutable ‘variables’ to functions and so 
just tend to use const or enum.


Re: enum and const or immutable ‘variable’ whose value is known at compile time

2020-09-16 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 16 September 2020 at 17:19:13 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward 
wrote:

then is there any downside to just using enum all the time?


For a non-string array, enum may give runtime allocations that 
static immutable won't.


Generally think of enum as being replaced with the literal 
representation and array literals actually make a new array.


This may or may not matter to you.


So can the result of declaring certain things with enum ever have 
an _address_ then? (According to legit D code that is, never mind 
the underlying implementation details, which may not be 
observable)


I actually really hate the way enum was bent out of shape 
and twisted from its original purpose so that finally we end up 
with a way of defining only one value, not the whole range of 
permissible values for a type as in the beginning.


I wish there were just a keyword ‘constant’ or something (yes, I 
know, you could just call that something ‘enum’, or 
‘const’)


Re: enum and const or immutable ‘variable’ whose value is known at compile time

2020-10-01 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 17 September 2020 at 01:57:39 UTC, Mike Parker wrote:

On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward


So can the result of declaring certain things with enum ever 
have an _address_ then? (According to legit D code that is, 
never mind the underlying implementation details, which may 
not be observable)


No. Think of it as a named literal.

Thank you Mike. That’s exactly what I thought. And it’s another 
reason in favour of using enum - that it forbids address-taking 
and so declares that there will be none.


New to GDC on ARM 32-bit Ubuntu

2018-07-16 Thread Cecil Ward via Digitalmars-d-learn
I am getting an error when I try and compile anything with the 
GDC compiler which is coming up associated with source code 
within a D include file which is not one of mine


I am using a Raspberry Pi with Ubuntu 16.04 and have just done an 
"apt-get install gdc". Using ldc works fine.


The error is :
root@raspberrypi:~#   gdc mac_hex.d -O3 -frelease
/usr/include/d/core/stdc/config.d:58:3: error: static if 
conditional cannot be at global scope

   static if( (void*).sizeof > int.sizeof )
   ^


This file has
==
version(Windows)
...
else version( Posix )
{
  static if( (void*).sizeof > int.sizeof )
  {
etc etc
==

It shows version
gdc --version
gdc (Ubuntu/Linaro 5.3.1-14ubuntu2) 5.3.1 20160413
Copyright (C) 2015 Free Software Foundation, Inc.

So that is unfortunately really old and I would love to get a new 
package


write a function template specialisation that tests if an argument is known at compile time

2018-08-10 Thread Cecil Ward via Digitalmars-d-learn

T myfunc(T)( T x, uint mask )
   if ( mask == 3 )
   {
   return fast_func( x, mask );
   }

but of course this doesn't work because mask is not known at 
compile-time. so I wondered if there is a way to do something 
like static if ( isKnownAtCompileTime( mask ) ) but that would 
not necessarily help me and probably isn't the right way.


Basically there is a fast path for certain known values of a 
(second in this case) argument where the compiler could produce 
superb trivial code or where I can work out a shortcut myself. 
for example myfunc( x, 0 ) == 0 and myfunc( x, -1 ) == x and 
various other good things, and for some values of mask the thing 
behaves like an AND operation so I want the compiler to just 
generate that.


The default slow path where the arg is unknown involves calling 
asm so the compiler cannot use its intelligence as it does not 
know the detailed semantics.


Also:

To add further complication: if both arguments of myfunc() are 
known at compile-time, then I definitely want to take an 
alternative path because then I can apply CTFE and calculate a 
compile-time result.


Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-10 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 11 August 2018 at 05:17:51 UTC, Cecil Ward wrote:

T myfunc(T)( T x, uint mask )
   if ( mask == 3 )
   {
   return fast_func( x, mask );
   }

but of course this doesn't work because mask is not known at 
compile-time.


Actually is there an opportunity for some kind of language 
enhancement there? I do not really know what I am talking about 
AT ALL but if the compiler could silently add an extra 
specialisation that gets generated at compile time, with constant 
folding and all the optimisations that follow from it, if a call 
with an appropriate constant argument is seen? But this is 
probably horrible because that kind of stuff is ph performed at a 
completely different point ?


Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-11 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 11 August 2018 at 18:11:15 UTC, Paul Backus wrote:

On Saturday, 11 August 2018 at 05:17:51 UTC, Cecil Ward wrote:

T myfunc(T)( T x, uint mask )
   if ( mask == 3 )
   {
   return fast_func( x, mask );
   }

but of course this doesn't work because mask is not known at 
compile-time. so I wondered if there is a way to do something 
like static if ( isKnownAtCompileTime( mask ) ) but that would 
not necessarily help me and probably isn't the right way.


You can create an overload where `mask` is passed as a template 
parameter:


T myfunc(uint mask, T)(T x)
{
static if(mask == 3) {
return fast_func(x, mask);
} else {
return func(x, mask);
}
}

The same technique is used by `std.format.format` in the 
standard library to pass a format string that's known at 
compile time.


Paul, what would the calls look like?

I am about to misunderstand things completely so here goes :-)

It would be a bit kludgy having to switch from one calling syntax 
to another, putting the mask argument in the template parameters 
or in the normal position. Or have I misunderstood? And if the 
caller did not use the right call syntax variant then the 
optimisation would not happen. Thing is, as it is the details are 
nicely hidden and the caller does not even need to thing about 
the fact that an (eponymous) template is being used.


Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-11 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 12 August 2018 at 00:55:50 UTC, Paul Backus wrote:

On Sunday, 12 August 2018 at 00:15:37 UTC, Cecil Ward wrote:

Paul, what would the calls look like?

I am about to misunderstand things completely so here goes :-)

It would be a bit kludgy having to switch from one calling 
syntax to another, putting the mask argument in the template 
parameters or in the normal position. Or have I misunderstood? 
And if the caller did not use the right call syntax variant 
then the optimisation would not happen. Thing is, as it is the 
details are nicely hidden and the caller does not even need to 
thing about the fact that an (eponymous) template is being 
used.


As far as I know, there's no way to *guarantee* the 
optimization and keep the normal function call syntax. Probably 
the best you can do is write the mask check as a regular if 
statement, put `pragma(inline, true)` in the function, and hope 
the optimizer is smart enough to get rid of the branch.


I was thinking about reflection and powerful things like traits. 
Would a test to see if a static if compile do the trick ? You ask 
the question using traits : "does the following compile? : { 
static if ( mask == 3 ) { }; }"  - any use?


Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-11 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 12 August 2018 at 02:17:21 UTC, Cecil Ward wrote:

On Sunday, 12 August 2018 at 00:55:50 UTC, Paul Backus wrote:

On Sunday, 12 August 2018 at 00:15:37 UTC, Cecil Ward wrote:

Paul, what would the calls look like?

I am about to misunderstand things completely so here goes :-)

It would be a bit kludgy having to switch from one calling 
syntax to another, putting the mask argument in the template 
parameters or in the normal position. Or have I 
misunderstood? And if the caller did not use the right call 
syntax variant then the optimisation would not happen. Thing 
is, as it is the details are nicely hidden and the caller 
does not even need to thing about the fact that an 
(eponymous) template is being used.


As far as I know, there's no way to *guarantee* the 
optimization and keep the normal function call syntax. 
Probably the best you can do is write the mask check as a 
regular if statement, put `pragma(inline, true)` in the 
function, and hope the optimizer is smart enough to get rid of 
the branch.


I was thinking about reflection and powerful things like 
traits. Would a test to see if a static if compile do the trick 
? You ask the question using traits : "does the following 
compile? : { static if ( mask == 3 ) { }; }"  - any use?


I am out of my depth but I am also wondering about using mixin in 
some way, conditionally.


And the kind of thing I am also thinking about is something like

   if this ( xxx ) compiles then xxx // put in the code under a 
conditional compilation if

   else pull in alternative code

and all the ifs are compile time. so zero run time penalty which 
absolutely essential in my case because in fact the bodies are 
just single instructions and it is a choice between a cheaper 
instruction ( or no instruction at all ) and a 3-4 times more 
costly instruction, but an if statement is 50 times more 
expensive because of branch misprediction risk as well as the 
cost of the test itself




Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-13 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 12 August 2018 at 12:27:59 UTC, Alex wrote:

On Saturday, 11 August 2018 at 05:17:51 UTC, Cecil Ward wrote:

T myfunc(T)( T x, uint mask )
   if ( mask == 3 )
   {
   return fast_func( x, mask );
   }

[...]


Is it the volcano pattern you are looking for?
https://p0nce.github.io/d-idioms/#Is-this-available-at-compile-time-or-runtime?


Wow, now that _is_ clever. I think that is definitely a big part 
of it.


Now somehow after having used a static if to select the 
known-at-compile-time case I then have to test the argument for 
particular values.


So how to get the next step along the way?



Re: write a function template specialisation that tests if an argument is known at compile time

2018-08-13 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 14 August 2018 at 02:53:01 UTC, Cecil Ward wrote:

On Sunday, 12 August 2018 at 12:27:59 UTC, Alex wrote:

On Saturday, 11 August 2018 at 05:17:51 UTC, Cecil Ward wrote:

T myfunc(T)( T x, uint mask )
   if ( mask == 3 )
   {
   return fast_func( x, mask );
   }

[...]


Is it the volcano pattern you are looking for?
https://p0nce.github.io/d-idioms/#Is-this-available-at-compile-time-or-runtime?


Wow, now that _is_ clever. I think that is definitely a big 
part of it.


Now somehow after having used a static if to select the 
known-at-compile-time case I then have to test the argument for 
particular values.


So how to get the next step along the way?


Would it be ok to ask Walter maybe ? I am so far out of my depth 
here tho.


Getting rid of const/immutable

2019-09-15 Thread Cecil Ward via Digitalmars-d-learn
I have a particular type name and that type may or may not be 
const and/or immutable. How do I make a new type based on this 
that is mutable, ie getting rid of both const and immutable, but 
not knowing what the original type is ?


I don’t want to repeat information from the definition of the 
original type as this would introduce a bug if the original 
definition is later changed.



Something like

alias immutable_cash_t = immutable(float);
alias mutable_cash_t = float;

// better, in case the original were ever to be changed from 
‘float’ to ‘real’ some day
alias mutable_cash_t = GetRidOfImmutable!( GetRidOfConst!( 
mutable_cash_t ) );


Writing a dejargoniser - producing read ke analysis output in English that explains GDC / LDC asm code’s parameters and clobbers

2023-04-05 Thread Cecil Ward via Digitalmars-d-learn
How much code do you thing I would need to write for this? I’m 
still thinking about its feasibility. I don’t want to invent the 
wheel and write a custom parser by hand, so’d rather steal the 
code using sim eg called ‘a library’. :-)


The idea would be that the user could run this to sanity-check 
her understanding of the sometimes arcane GDC asm code 
outputs/inputs/clobbers syntax, and see what her asm code’s 
constraints are actually going to do rather than what she thinks 
it’s going to do. Clearly I can’t readily start parsing the asm 
body itself, I would just inspect the meta info. (If that’s the 
right word?)


I would have a huge problem with LDC’s alternative syntax unless 
I could think of some way to pre-transform and munge it into GDC 
format.


I do wish LDC (and DMD) would now converge on the GDC asm syntax. 
Do you think that’s reasonably doable?


Re: std.socket tutorials? examples?

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 29 April 2023 at 11:26:20 UTC, Adam D Ruppe wrote:

On Saturday, 29 April 2023 at 10:56:46 UTC, Jan Allersma wrote:

auto clientResult = Socket.select(clientSet, null, null);



There's probably nothing in clientSet, so it is waiting for 
nothing you almost always want to have just one call to 
select in the program, not two, the whole point is to combine 
checks.


I wrote a thing you might want to read too:

http://dpldocs.info/this-week-in-d/Blog.Posted_2019_11_11.html#sockets-tutorial


How do we wait for an ‘or’ of multiple asynchronous events in 
this kind of code? In WinNT iirc there is a very nice o/s 
function that can wait on various kinds of asynch i/o, waiting on 
operations of different types if I’ve understood it correctly. 
The kind of thing I might want to do is wait on an or of IP 
packets arriving, send-completion of IP packets, timers 
completing, IPC messages coming in, key presses or event mouse 
events and the order in which these events arrive is of course 
not predictable. I might want a key press event to break out of 
something or to control an application. Everyone wants timer 
events for timeouts.


Re: std.socket tutorials? examples?

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 30 April 2023 at 22:37:48 UTC, Adam D Ruppe wrote:

On Sunday, 30 April 2023 at 22:10:31 UTC, Cecil Ward wrote:
How do we wait for an ‘or’ of multiple asynchronous events in 
this kind of code?


You can set a timeout value for Socket.select, but Phobos isn't 
going to help you with anything other than sockets and timeouts 
(despite the fact the underlying operating systems can, in 
fact, do it).


There's a few other libs that can help with this, including one 
I'm aiming to release some time in May, or vibe.d has its own 
ways of doing it, among others. You can also import 
core.sys.stuff and call the OS functions without a middle man.


But the D stdlib is quite underpowered when it comes to these 
things. Socket.select is ok but just the basics.


Many thanks, Adam.


Re: quick question, probably of little importance...

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 26 April 2023 at 23:07:39 UTC, WhatMeWorry wrote:
On Wednesday, 26 April 2023 at 23:02:07 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

Don't forget ``num % 2 == 0``.

None should matter, pretty much all production compilers 
within the last 30 years should recognize all forms of this 
and do the right thing.


Thanks. Fastest reply ever! And I believe across the world?   I 
suppose my examples required overhead of a function call. So 
maybe num % 2 == 0 is fastest?


I made a small change, making the retval a bool rather than an 
int. I got slightly better code generation with the int, as it 
seems that some of the compilers have not yet got all the good 
tricks they should be using when manipulating bool-typed 
expressions and also it can be one extra instruction converting 
values to bool strictly zero or one, not zero or any non-zero 
value. Here’s the D, enlarged a little so that we can see your 
routine in action, inlined. Your isEven boils down to two 
instructions with a seriously optimising compiler. I’ve included 
the x86-64 machine code generated by the GDC and LDC compilers so 
you can see how fast it is. GDC made a bit of a dog’s breakfast 
of my longer routine whereas LDC performed superbly. GDC 
generated twice as much code, but its excellent instruction 
scheduler and what looks like an awareness of ILP mean that the 
two streams of instructions will be carried out in parallel  so 
the two streams will only take three instruction times - ie 
whatever the total time is for those three instruction in the one 
stream - not six.


bool isEven( int num )
{
return ! ( num & 1 );
}

bool AreBothEven( int a, int b )  // returns true if both 
arguments are even

{
return isEven( a )  &&  isEven( b );
}

===
Compiler output:: GDC:: x86-64: -O3 -mcpu=native -frelease

bool isEven( int ):
mov eax, edi
not eax
and eax, 1
ret

bool AreBothEven( int, int ):
mov eax, edi
not esi
not eax
and esi, 1
and eax, 1
cmovne  eax, esi
ret

===
Compiler LDC: x86-64: -O3 -mcpu=native -release

bool isEven( int ):
testdil, 1
seteal
ret

bool AreBothEven( int, int ):
or  edi, esi
testdil, 1
seteal
ret


Re: quick question, probably of little importance...

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 1 May 2023 at 03:53:24 UTC, Cecil Ward wrote:

On Wednesday, 26 April 2023 at 23:07:39 UTC, WhatMeWorry wrote:

[...]




Correction: I can’t count. There are only two instructions in 
parallel with another pair running alongside, not three. The 
first reg, reg move counts as zero cycles, so the total time is 
just the sum of the following three instructions’ times, ignoring 
the other parallel stream.


Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-29 Thread Cecil Ward via Digitalmars-d-learn
I have often come into difficulties where I wish to have one 
routine that can be called with either immutable or (possibly) 
mutable argument values. The argument(s) in question are in, 
readonly, passed by value or passed by const reference. Anyway, 
no one is trying to write to the items passed in as args, no 
badness attempted.


When I call the routine from one place with an argument that is 
immutable and then from another that is not, or it could be const 
as well, or not, that’s when I get all kinds of type mismatch 
errors. And I certainly don’t want to pour cast-like type 
conversion operations over all the place at these problem 
occurrences. it’s surely asking for problems.


Could I make the one routine into a template? Even if I did, that 
would perhaps create additionally problems, since even if it all 
worked and instantiated either immutable or mutable forms of the 
routine, what happens if I have two args and they have a mixture 
of immutable and no immutable args ? So nargs * 2 ( or more) 
possibilities?


I’m out of my depth here.


Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-30 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 30 May 2023 at 04:15:22 UTC, Ali Çehreli wrote:

On 5/29/23 19:57, Cecil Ward wrote:

> I wish to have one routine
> that can be called with either immutable or (possibly)
mutable argument
> values.

'const' should take both immutable and mutable. Can you show 
your case with a short example?


> Could I make the one routine into a template?

That could work but give 'in' parameters a try:

  https://dlang.org/spec/function.html#in-params

Ali


T2 foo( in T1 x ) { return bar( x ) };

It was with something vaguely like the above that I had to remove 
the in (templatised generic function possibly) in order to get it 
to compile with GDC or LDC on godbolt.org (or d.godbolt.org) 
latest versions available. -O3 -release/-frelease 
-march=native/-mcpu-native





Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 03:23:01 UTC, Cecil Ward wrote:

On Tuesday, 30 May 2023 at 04:15:22 UTC, Ali Çehreli wrote:

On 5/29/23 19:57, Cecil Ward wrote:

> I wish to have one routine
> that can be called with either immutable or (possibly)
mutable argument
> values.

'const' should take both immutable and mutable. Can you show 
your case with a short example?


> Could I make the one routine into a template?

That could work but give 'in' parameters a try:

  https://dlang.org/spec/function.html#in-params

Ali


T2 foo( in T1 x ) { return bar( x ) };

It was with something vaguely like the above that I had to 
remove the in (templatised generic function possibly) in order 
to get it to compile with GDC or LDC on godbolt.org (or 
d.godbolt.org) latest versions available. -O3 
-release/-frelease -march=native/-mcpu-native


I have to admit that I don’t really understand immutable. I have 
an idea that it could mean that an object has an address in ROM, 
so its value will never change. Maybe const doesn’t give you such 
a strong guarantee, disallows ‘you’ from modifying it but others 
might do so, but who knows. Without a guarantee as strong as the 
first idea I can’t really understand how const can work properly. 
"You treat it as const so do not modify it, but it might not be 
eternally fixed and  unchanging" that doesn’t seem to have enough 
value to me. But maybe I’ve got the whole thing wrong.


In an architecture where you have strongly typed (tagged ? 
segmented?) different kinds of addresses, I can see why you might 
be getting type mismatch errors when passing addresses around.


Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 09:14:49 UTC, Dom DiSc wrote:

On Wednesday, 31 May 2023 at 03:29:33 UTC, Cecil Ward wrote:
I have to admit that I don’t really understand immutable. I 
have an idea that it could mean that an object has an address 
in ROM, so its value will never change. Maybe const doesn’t 
give you such a strong guarantee, disallows ‘you’ from 
modifying it but others might do so, but who knows.
There are two perspectives: that of the value handed to a 
function and that of the function taking the value.
"immutable" (or "mutable") is a property of the value, "const" 
is a property of the function.
If the function can work with mutable values, but in fact 
doesn't mutate them itself, it could also work with immutable 
values. The fact that others could modify your "const" value 
doesn't matter for immutable values, because they of course 
can't be modified by others. For the function it doesn't 
matter, because it only guarantees not to modify it itself, 
don't care about what other can or can't do.



Without a guarantee as strong as the first idea I can’t really
understand how const can work properly. "You treat it as const
so do not modify it, but it might not be eternally fixed and
unchanging" that doesn’t seem to have enough value to me.

Why? What guarantee are you missing?
Your function can work with mutable data, so you don't care if 
it can be modified also by others.
Now it happens that you doesn't modify the data. So why 
shouldn't you be able to work on data that guarantees that it 
also will not be changed by others? You don't care for such 
modification anyway.


The meaning of "immutable" is: I cannot be modified. Not by you 
and not by anybody else. It's a property of a value.
The meaning of "mutable" is: I can be modified by anybody. Work 
with me only if that is ok for you. It's a property of a value.
The meaning of "const" is: I don't care if others modify the 
data or not, I won't modify it myself. It's a property of a 
function.


Dom, you explain it well. I’m just too stupid. Literally, as I’m 
on strong pain drugs all the time, so things are a bit fuzzy. As 
a professional C programmer for some years, I understood the word 
const and used it all the time, as much as possible at every 
opportunity, so I had some expectations. But the errors I’m 
getting don’t fit in with the previous understanding I had with 
the familiar ‘const’ keyword and make me think there must be 
something else going on. So I will need to capture an example in 
the wild, cage it and bring it in for scientific examination.


I can’t ask for an explanation of things going on that you can’t 
inspect for yourself, obviously. And I don’t understand what the 
problem is with using in as much as possible yet having to remove 
it sometimes when something immutable is in use.


Indenting standards religions K&R, whitesmiths etc

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
I wanted to ask how some of the leaders of our group feel about D 
indentation standards. `i realise that this causes some religious 
fervour in C. I could be in trouble here because in all my years 
at work, we never used K & R ‘one true brace style’ indenting, 
with the house style I’m used to being more like whitesmiths. 
Wikipedia explains this better. Something like the following 
below.


So my question: would I get lynched for the following? (below)

And can anyone recommend a beautifier / pretty printer tool for D 
that is customisable to your house style if that is a thing 
that’s needed? I assume I would need that if I were to donate 
code, unless some helpful recipient would run such a tool on .d 
files received.


—

pure nothrow etc
T
foo( T, T2 )(
in T param x,
in T2 param y
)
if ( template-qualification-whatever )
in {
static assert( … );
}
out ( ret )
{
…
assert( test ret );
}
do   {
blah
if ( test ) {
…
if-body
…
}
back to main block
…
…
} /* end of function, notice the indent level stays out 
with the content */


How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
Is there an explanation of how D’s ‘import’ works somewhere? I’m 
trying to understand the comparison with the inclusion of .h 
files, similarities if any and differences with the process.


Re: Indenting standards religions K&R, whitesmiths etc

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 31 May 2023 at 22:06:50 UTC, Ernesto Castellotti 
wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


[...]



Excuse me but for me the only style I like is the K&R.
I can accept Allman but the rest is heretical to me ;-) don't 
worry, just a joke


Is there even such as thing as a pretty-printer / beautifier for 
D ? Has anyone adapted one ?


`it might save me from a lynch mob. :-) :-)


Re: How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 18:56:02 UTC, H. S. Teoh wrote:
On Wed, May 31, 2023 at 06:43:52PM +, Cecil Ward via 
Digitalmars-d-learn wrote:
Is there an explanation of how D’s ‘import’ works somewhere? 
I’m trying to understand the comparison with the inclusion of 
.h files, similarities if any and differences with the process.


Unlike C's #include, `import` does NOT paste the contents of 
the imported file into the context of `import`, like #include 
would do. Instead, it causes the compiler to load and parse the 
imported file, placing the parsed symbols into a separate 
symbol table dedicated for that module (in D, a file == a 
module). These symbols are then pulled into the local symbol 
table so that they become available to code containing the 
import declaration.


(There's a variation, `static import`, that does the same thing 
except the last step of pulling symbols into the local symbol 
table. So the symbols will not "pollute" the current namespace, 
but are still accessible via their fully-qualified name (FQN), 
i.e., by the form `pkg.mod.mysymbol`, for a symbol `mysymbol` 
defined in the module `pkg.mod`, which in turn is a module 
under the package `pkg`.)


For more information:

https://tour.dlang.org/tour/en/basics/imports-and-modules
https://dlang.org/spec/module.html


T


Thank you so very much for the links and for your generous help. 
Some C compilers used to have a thing called ‘precompiled 
headers’, potential source of trouble and ai always felt uneasy 
about it rightly or wrongly.


It’s great that D has got rid of header file includes though, 
they were ridiculously painful. I used to use the automake 
feature that was built into the JPI C compiler at work which took 
care of all the .h dependencies so you no longer had to worry 
about it. And you only loaded the compiler from disk and started 
it up once as it stayed in memory handling all the C parts of a 
make.




Re: How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 18:43:52 UTC, Cecil Ward wrote:
Is there an explanation of how D’s ‘import’ works somewhere? 
I’m trying to understand the comparison with the inclusion of 
.h files, similarities if any and differences with the process.


I have another question if I may, what do we do about getting 
makefiles right given that we have imports ?


Re: Indenting standards religions K&R, whitesmiths etc

2023-06-01 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 1 June 2023 at 09:37:43 UTC, Dukc wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


So my question: would I get lynched for the following? (below)


Check out this module from me: 
https://github.com/dukc/nuklearbrowser/blob/master/source/nuklearbrowser.d


Plus similar style in most of my posts and bug reports. I'm 
still alive :D.


Your code is your code. There, you may do as you wish. You have 
to aknowledge that an esoteric style may make it more difficult 
to read for some, but we're not lynching people for other 
factors of code readability either. Brace style is no different.


Plus, what brace style is considered readable by the majority 
is a culture issue. There has to be some way to challege the 
established culture. If you don't exercise your power to code 
as you wish, someone will make your choice for you. Coding 
culture, or even culture in general, cannot develop if people 
never challege the present status quo.


When you're coding with others, though, then you should obey 
the style guideline of that project if there is one. Even there 
you're as entitled as anyone for an opinion what the style 
policy should be (and to whether there should be style policy 
at all), but you then should (usually) obey the decision 
regardless whether it's the one you were advocating for.


Agree completely. You are not a criminal though because your 
closing braces are not indented out with the block they’re 
closing as I do.


I find K&R hard to read even though we see it everywhere, or 
variants of it. I do wonder if my style in that earlier post 
hurts normal people’s eyeballs a lot. ;-)


I’m told that Irish speakers can’t understand Scottish Gaelic on 
the radio a native speaker said to me that ‘it’s just a noise’. 
But as a ScG learner myself I can understand some spoken Irish 
even though I’ve never really studied the modern language (only 
the stuff of more that 1100 yrs ago.) So the pain isn’t 
symmetrical.


Re: Indenting standards religions K&R, whitesmiths etc

2023-06-01 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 1 June 2023 at 09:37:43 UTC, Dukc wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


So my question: would I get lynched for the following? (below)


Check out this module from me: 
https://github.com/dukc/nuklearbrowser/blob/master/source/nuklearbrowser.d


Plus similar style in most of my posts and bug reports. I'm 
still alive :D.


Your code is your code. There, you may do as you wish. You have 
to aknowledge that an esoteric style may make it more difficult 
to read for some, but we're not lynching people for other 
factors of code readability either. Brace style is no different.


Plus, what brace style is considered readable by the majority 
is a culture issue. There has to be some way to challege the 
established culture. If you don't exercise your power to code 
as you wish, someone will make your choice for you. Coding 
culture, or even culture in general, cannot develop if people 
never challege the present status quo.


When you're coding with others, though, then you should obey 
the style guideline of that project if there is one. Even there 
you're as entitled as anyone for an opinion what the style 
policy should be (and to whether there should be style policy 
at all), but you then should (usually) obey the decision 
regardless whether it's the one you were advocating for.


I wonder how much work it would be to write a D pretty printer / 
beautifier. Doing things such as lining up parameters or comments 
and breaking and re-wrapping comments etc if necessary because of 
the changes in whitespace.


I’ve no idea what the ‘official story’ is with nested functions. 
I have some experience with that because I used to write Pascal 
(on a Z80 box and on a VAX), and that feature is like the return 
of an old friend, I love it so much and for me it’s quite a 
serious advantage over C.


I’m always guilty of overcommenting, for various reasons although 
I’m not guilt of the likes of /* add 1 to x */!  ;-) It’s partly 
because I have a shocking memory and maintenance becomes 
literally impossible for me, for me just as important I want the 
comments to spell out original intent, not the implementation 
choices, so if you see later that the two don’t match then you’ve 
spotted the bug.


Many people comment in a very minimal way which makes the code 
look neat.


I did sort of find an /* add 1 to x */ though as it was 
explaining and giving a caveat about GCC in-line asm constraints, 
and the comment saved me having to go and look things up in the 
bible.


Re: How does D’s ‘import’ work?

2023-06-07 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 2 June 2023 at 12:07:09 UTC, rempas wrote:

On Thursday, 1 June 2023 at 03:47:00 UTC, Cecil Ward wrote:


I have another question if I may, what do we do about getting 
makefiles right given that we have imports ?


What do you mean with that? Give some more info please!


I was thinking about the situation in C where I have a rule in a 
make file that lists the .h files as well as the .c all as 
dependencies in creating an object file.


Re: byte and short data types use cases

2023-06-09 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:
Hi, I was interested why, for example, `byte` and `short` 
literals do not have their own unique suffixes (like `L` for 
`long` or `u` for `unsigned int` literals) and found the 
following explanation:


- "I guess short literal is not supported solely due to the 
fact that anything less than `int` will be "promoted" to `int` 
during evaluation. `int` has the most natural size. This is 
called integer promotion in C++."


Which raised another question: since objects of types smaller 
than `int` are promoted to `int` to use integer arithmetic on 
them anyway, is there any point in using anything of integer 
type less than `int` other than to limit the range of values 
that can be assigned to a variable at compile time? Are these 
data types there because of some historical reasons (maybe 
`byte` and/or `short` were "natural" for some architectures 
before)?


People say that there is no advantage for using `byte`/`short` 
type for integer objects over an int for a single variable, 
however, as they say, this is not true for arrays, where you 
can save some memory space by using `byte`/`short` instead of 
`int`. But isn't any further manipulations with these array 
objects will produce results of type `int` anyway? Don't you 
have to cast these objects over and over again after 
manipulating them to write them back into that array or for 
some other manipulations with these smaller types objects? Or 
is this only useful if you're storing some array of constants 
for reading purposes?


Some people say that these promoting and casting operations in 
summary may have an even slower overall effect than simply 
using int, so I'm kind of confused about the use cases of these 
data types... (I think that my misunderstanding comes from not 
knowing how things happen at a slightly lower level of 
abstractions, like which operations require memory allocation, 
which do not, etc. Maybe some resource recommendations on 
that?) Thanks!


For me there are two use cases for using byte and short, ubyte 
and ushort.


The first is simply to save memory in a large array or neatly fit 
into a ‘hole’ in a struct, say next to a bool which is also a 
byte. If you have four ubyte variables in a struct and then an 
array of them, then you are getting optimal memory usage. In the 
x86 for example the casting operations for ubyte to uint use 
instructions that have zero added cost compared to a normal uint 
fetch. And casting to a ubyte generates no code at all. So the 
costs of casting in total are zero.


The second use-case is where you need to interface to external 
specifications that deman uint8_t (ubyte), or uint16_t (ushort) 
where I am using the standard definitions from std.stdint. These 
types are the in C. If you are interfacing to externally defined 
struct in data structures in ram or in messages, that’s one 
example. The second example is where you need to interface to 
machine code that has registers or operands of 8-bit or 16-bit 
types. I like to use the stdint types for the purposes of 
documentation as it rams home the point that these are truly 
fixed width types and can not change. (And I do know that in D, 
unlike C, int, long etc are of defined fixed widths. Since C 
doesn’t have those guarantees that’s why the C stdint.h is needed 
in C too.) As well as machine code, we could add other high-level 
languages where interfaces are defined in the other language and 
you have to hope that the other language’s type widths don’t 
change.


Re: byte and short data types use cases

2023-06-09 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:

If you have four ubyte variables in a struct and then
an array of them, then you are getting optimal memory usage.


Is this some kind of property? Where can I read more about this?

So you can optimize memory usage by using arrays of things 
smaller than `int` if these are enough for your purposes, but 
what about using these instead of single variables, for example 
as an iterator in a loop, if range of such a data type is 
enough for me? Is there any advantages on doing that?


Read up on ‘structs’ and the ‘align’ attribute in the main d 
docs, on this website. Using smaller fields in a struct that is 
in memory saves RAM if there is an array of such structs. Even in 
the case where there is only one struct, let’s say that you are 
returning a struct by value from some function. If the struct is 
fairly small in total, and the compiler is good (ldc or gdc, not 
dmd - see godbolt.org) then the returned struct can fit into a 
register sometimes, rather than being placed in RAM, when it is 
returned to the function’s caller. Yesterday I returned a struct 
containing four uint32_t fields from a function and it came back 
to the caller in two 64-bit registers, not in RAM. Clearly using 
smaller fields if possible might make it possible for the whole 
struct to be under the size limit for being returned in registers.


As for your question about single variables. The answer is very 
definitely no. Rather, the opposite: always use primary 
CPU-‘natural’ types, widths that are most natural to the 
processor in question. 64-bit cpus will sometimes favour 32-bit 
types an example being x86-64/AMD64, where code handling 32-bit 
ints generates less code (saves bytes in the code segment) but 
the speed and number of instructions is the same on such a 64-bit 
processor where you’re dealing with 32- or 64- bit types. Always 
use size_t for index variables into arrays or the size of 
anything in bytes, never int or uint. On a 64-bit machine such as 
x86-64, size_t is 64-bit, not 32. By using int/uint when you 
should have used size_t you could in theory get a very rare bug 
when dealing with eg file sizes or vast amounts of (virtual) 
memory, say bigger than 2GB (int limit) or 4GB (uint limit) when 
the 32-bit types overflow. There is also a ptrdiff_t which is 
64-bit on a 64-bit cpu, probably not worth bothering with as its 
raison d’être was historical (early 80s 80286 segmented 
architecture, before the 32-bit 386 blew it away).


Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:

If you have four ubyte variables in a struct and then
an array of them, then you are getting optimal memory usage.


Is this some kind of property? Where can I read more about this?

So you can optimize memory usage by using arrays of things 
smaller than `int` if these are enough for your purposes, but 
what about using these instead of single variables, for example 
as an iterator in a loop, if range of such a data type is 
enough for me? Is there any advantages on doing that?


A couple of other important use-cases came to me. The first one 
is unicode which has three main representations, utf-8 which is a 
stream of bytes each character can be several bytes, utf-16 where 
a character can be one or rarely two 16-bit words, and utf32 - a 
stream of 32-bit words, one per character. The simplicity of the 
latter is a huge deal in speed efficiency, but utf32 takes up 
almost four times as memory as utf-8 for western european 
languages like english or french. The four-to-one ratio means 
that the processor has to pull in four times the amount of memory 
so that’s a slowdown, but on the other hand it is processing the 
same amount of characters whichever way you look at it, and in 
utf8 the cpu is having to parse more bytes than characters unless 
the text is entirely ASCII-like.


The second use-case is about SIMD. Intel and AMD x86 machines 
have vector arithmetic units that are either 16, 32 or 64 bytes 
wide depending on how recent the model is. Taking for example a 
post-2013 Intel Haswell CPU, which has 32-byte wide units, if you 
choose smaller width data types you can fit more in the vector 
unit - that’s how it works, and fitting in more integers or 
floating point numbers of half width means that you can process 
twice as many in one instruction. On our Haswell that means four 
doubles or four quad words, or eight 32-bit floats or 32-bit 
uint32_ts, and similar doubling s’s for uint16_t. So here width 
economy directly relates to double speed.


Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 10 June 2023 at 21:58:12 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

[...]


Is this some kind of property? Where can I read more about 
this?


My last example is comms. Protocol headers need economical narrow 
data types because of efficiency, it’s all about packing as much 
user data as possible into each packet and fatter, longer headers 
reduce the amount of user data as the total has a hard limit on 
it. A pair of headers totalling 40 bytes in IPv4+TCP takes up 
nearly 3% of the total length allowed, so that’s a ~3% speed 
loss, as the headers are just dead weight. So here narrow types 
help comms speed.


Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 11 June 2023 at 00:05:52 UTC, H. S. Teoh wrote:
On Sat, Jun 10, 2023 at 09:58:12PM +, Cecil Ward via 
Digitalmars-d-learn wrote:

On Friday, 9 June 2023 at 15:07:54 UTC,



[...]

On contemporary machines, the CPU is so fast that memory access 
is a much bigger bottleneck than processing speed. So unless an 
operation is being run hundreds of thousands of times, you're 
not likely to notice the difference. OTOH, accessing memory is 
slow (that's why the memory cache hierarchy exists). So utf8 is 
actually advantageous here: it fits in a smaller space, so it's 
faster to fetch from memory; more of it can fit in the CPU 
cache, so less DRAM roundtrips are needed. Which is faster.  
Yes you need extra processing because of the variable-width 
encoding, but it happens mostly inside the CPU, which is fast 
enough that it generally outstrips the memory roundtrip 
overhead. So unless you're doing something *really* complex 
with the utf8 data, it's an overall win in terms of 
performance. The CPU gets to do what it's good at -- running 
complex code -- and the memory cache gets to do what it's good 
at: minimizing the amount of slow DRAM roundtrips.




I completely agree with H. S. Teoh. That is exactly what I was 
going to say. The point is that considerations like this have to 
be thought through carefully and width of types really does 
matter in the cases brought up.


But outside these cases, as I said earlier, stick to uint, size_t 
and ulong, or uint32_t and uint64_t if exact size is vital, but 
do also check out the other std.stdint types too as very 
occasionally they are needed.




  1   2   >