Re: is my code to get CTFE instantiated object valid D ?
On Friday, 27 May 2016 at 21:41:02 UTC, Kagamin wrote: On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote: Is this code valid D or is the behavior undefined due to the cast ? A mutable object can be synchronized on: synchronized(Category.instance){} This will create and store a mutex in the object (sad but true, design taken from java). If the immutable object is in readonly memory, it will crash on write. That is a good argument. Thanks. It would indeed be a good idea to put immutable objects in a read only portion of the code. Would it be different if the object was declared const instead of immutable ? I want compile time instantiation and mutable references to the object. Apparently only immutable and const objects can be instantiated at compile time. I also want an app wide singleton (not stored in TLS). If I use _gshared I apparently wouldn't get a compile time instantitation. It's to implement the flyweight pattern. I don't want to use Rebindable because the assembly code generated by dmd is currently inefficient. Rebindable cast away the const but the non constant reference is not exposed. What is the difference between a const and immutable object ? would a const object be allowed to modify itself by using a hash table or caching results inside ? Is a static const Category c variable a TLS variable ? This is a bit frustrating because it is trivial to implement in C and C++.
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 20:59:56 UTC, John wrote: Additionally, remove QueryInterface, AddRef and Release from the definition of IDirectSound. Also, interfaces are already references, so the definition of LPDIRECTSOUND should be: alias LPDIRECTSOUND = IDirectSound; Note there should be no *. Awesome... that's the missing link. Thank you very. I really appreciate the assistance of everyone who helped to clarify this matter. Regarding any linking errors, it's easier to either grab the .lib files from the Windows SDK and convert them with coffimplib, or use the m32mscoff switch so you can link with the SDK .lib files directly. Was already doing that (both approaches). As Adam pointed out, last bit of errors were occurring because it was a class vice an interface. Again, thank you all. Andrew
Does this C callback call look correct?
// Specification from ALURE documentation ALURE_API ALboolean ALURE_APIENTRY alurePlaySourceStream( ALuint source, alureStream *stream, ALsizei numBufs, ALsizei loopcount, void(*eos_callback)(void *userdata, ALuint source), void*userdata ) // My D code, below compiles and links and when I execute it // I get a beep sound (which is as expected), but ALURE never // calls my eos_callback function no matter how long I wait. extern (C) void eos_callback(void *unused, ALuint unused2) { writeAndPause("End Of Streaming"); } if (alurePlaySourceStream( source, stream, numBuffs, loopStreamCount, _callback,// end of stream callback cast (void *) 0) == AL_FALSE) Am I missing something? I'm using Derelict ALURE. I've looked on github but there seems to be no D code using this technique.
Re: is my code to get CTFE instantiated object valid D ?
On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote: The public interface of Category is designed so that the object's state can't be modified and thus remains immutable. Then... why cast away immutable? I suppose there's always a core set of variables that are what the object actually considers for it's constness, while there's other extra ones for convenience (say lookup hash tables, memoize and the like) which assist but their presence or lack thereof only affects speed rather than function...
Re: is my code to get CTFE instantiated object valid D ?
On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote: Is this code valid D or is the behavior undefined due to the cast ? A mutable object can be synchronized on: synchronized(Category.instance){} This will create and store a mutex in the object (sad but true, design taken from java). If the immutable object is in readonly memory, it will crash on write.
Re: Request assistance binding to Windows dsound.{lib, dll}
Additionally, remove QueryInterface, AddRef and Release from the definition of IDirectSound. Also, interfaces are already references, so the definition of LPDIRECTSOUND should be: alias LPDIRECTSOUND = IDirectSound; Note there should be no *. Regarding any linking errors, it's easier to either grab the .lib files from the Windows SDK and convert them with coffimplib, or use the m32mscoff switch so you can link with the SDK .lib files directly.
Re: is my code to get CTFE instantiated object valid D ?
On 5/27/16 4:20 PM, chmike wrote: I need to create an app wide singleton instance for my class. The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests. I declared this class Category { protected static immutable Category instance_ = new Category; Category instance() { return cast(Category)instance_; } ... } It compiles and the instance should be instantiated at compile time. I couldn't check yet. The public interface of Category is designed so that the object's state can't be modified and thus remains immutable. Is this code valid D or is the behavior undefined due to the cast ? You can cast away immutable. You just can't mutate. Hard to say without seeing what the ... is. A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ? No. Undefined behavior if you modify immutable data. -Steve
is my code to get CTFE instantiated object valid D ?
I need to create an app wide singleton instance for my class. The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests. I declared this class Category { protected static immutable Category instance_ = new Category; Category instance() { return cast(Category)instance_; } ... } It compiles and the instance should be instantiated at compile time. I couldn't check yet. The public interface of Category is designed so that the object's state can't be modified and thus remains immutable. Is this code valid D or is the behavior undefined due to the cast ? A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ?
Re: Easier way to add libraries to visual d?
On Thursday, 26 May 2016 at 22:15:17 UTC, Basile B. wrote: gfm doesn't yield a .lib because of this: https://github.com/d-gamedev-team/gfm/blob/master/dub.json#L22 it should be "library" or staticLibrary or "sourceLibrary" thus it can't be registered. Bad luck here you've chosen the wrong stuff to test. Okay, i now tried requests and serial-port and with both i have the same problem that i can't add them to the library manager.
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 17:49:56 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 17:37:38 UTC, Andrew Edwards wrote: extern (C) class IDirectSound : IUnknown That should just be `interface IDirectSound : IUnknown` Thanks for the clarification. That actually compiles but results in access violation at the call site which takes place after verifying that the call to DirectSoundCreate() succeeded: if (SUCCEEDED(sound.SetCooperativeLevel(window, DSSCL_PRIORITY))) { MessageBoxA(null, "Hott Damn!!", null, MB_ICONINFORMATION); } else { MessageBoxA(null, "Naaah Man! Dat cyaan wuk!", null, MB_ICONINFORMATION); } Output: object.Error@(0): Access Violation -- 0x00402700 in void sound.initSound(void*) at C:\Users\edwarac\work\sound\code\sound.d(555) 0x004021A2 in int sound.myWinMain(void*, void*, char*, int) at C:\Users\edwasac\work\sound\code\sound.d(210) 0x00402050 in WinMain at C:\Users\edwasac\work\sound\code\sound.d(154) 0x00422B4A in WinMainCRTStartup 0x76DF3744 in BaseThreadInitTrunk 0x7721A064 in RtlSetCurrentTransaction 0x7721A02F in RtlSetCurrentTransaction
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 18:03:23 UTC, Steven Schveighoffer wrote: I didn't change the default. The default is to pick the first member and use that as the init value. I may not have even considered what foo.init might be when I was creating my enum. -Steve by default i ment this enum foo { bar } foo f; if(f) "dosnt print".writeln; but i understand what you mean which adds a problem to my checkThen template, as the return type of the template depends on the return type of the callable which right now returns the init value of the callable return type if the type you pass into the template evaluates to false. an example: class Foo { int x; } Foo foo(){ return null; } foo.checkThen!( f => f.x = 5; ).writeln; // writes f.x.init because i kinda need a common return type if foo wouldnt return null
Re: Why do some T.init evaluate to true while others to false?
On 5/27/16 1:42 PM, ArturG wrote: On Friday, 27 May 2016 at 16:56:21 UTC, Steven Schveighoffer wrote: Why are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too"); but by default it works you just changed the default so its ok that it doesnt work. I didn't change the default. The default is to pick the first member and use that as the init value. I may not have even considered what foo.init might be when I was creating my enum. -Steve
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 17:37:38 UTC, Andrew Edwards wrote: extern (C) class IDirectSound : IUnknown That should just be `interface IDirectSound : IUnknown`
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 16:56:21 UTC, Steven Schveighoffer wrote: Why are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too"); -Steve but by default it works you just changed the default so its ok that it doesnt work.
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 16:08:27 UTC, Kagamin wrote: On Friday, 27 May 2016 at 15:28:42 UTC, Andrew Edwards wrote: Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and @12 decorations (would be __stdcall on C/C++ side) The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded. If you declare extern function with wrong calling convention, calling it can result in stack corruption. Okay, that makes sense. Will remain mindful of that. Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented. This struct is called COM interface, D has built-in support for them: https://dlang.org/spec/interface.html#com-interfaces So if I'm understanding correctly, I should be able to take this: DECLARE_INTERFACE_(IDirectSound, IUnknown) { // IUnknown methods STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; STDMETHOD_(ULONG,AddRef)(THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; // IDirectSound methods STDMETHOD(CreateSoundBuffer)(THIS_ LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN) PURE; STDMETHOD(GetCaps) (THIS_ LPDSCAPS) PURE; STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER *) PURE; STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE; STDMETHOD(Compact) (THIS) PURE; STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE; STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE; STDMETHOD(Initialize) (THIS_ LPGUID) PURE; }; Convert it into this: extern (C) class IDirectSound : IUnknown { // IUnknown methods HRESULT QueryInterface(const(IID)*, void**); uint AddRef(); uint Release(); // IDirectSound methods HRESULT CreateSoundBuffer(LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER*, LPUNKNOWN); HRESULT GetCaps(LPDSCAPS); HRESULT DuplicateSoundBuffer(LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER*); HRESULT SetCooperativeLevel(HWND, DWORD); HRESULT Compact(); HRESULT GetSpeakerConfig(LPDWORD); HRESULT SetSpeakerConfig(DWORD); HRESULT Initialize(LPGUID); } Import the correct libraries: import core.sys.windows.windows; import core.sys.windows.com; And finally link to the lib file and I should be golden!!! Except I'm not :( C:\Users\edwarac\work\sound\code>build A subdirectory or file ..\..\build already exists. OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound17CreateÇàìBufferMWxPSÇï»DSBUFFERDESCPPCÇèÜ8Çî╔Çå╝C4core3sys7windows6unknwn8IU·ownZi@12 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound16SetSpeakerConfigMWkZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound16GetSpeakerConfigMWPkZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound7CompactMWZi@0 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound20DuplicateSoundBufferMWPC8sound18IDirectSoundBufferPPC8sound18IDirectSoundBufferZi@8 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound19SetCooperativeLevelMWPvkZi@8 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound10InitializeMWPS4core3sys7windows8basetyps4GUIDZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound12IDirectSound7GetCapsMWPS8sound6DSCAPSZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer12GetFrequencyMWPkZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6SetPanMWiZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9GetFormatMWPS4core3sys7windows8mmsystem12WAVEFORMATEXkPkZi@12 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer7RestoreMWZi@0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer6GetPanMWPiZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer4StopMWZi@0 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9GetStatusMWPkZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer4LockMWkkPPvPkPPvPkkZi@28 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer7GetCapsMWPS8sound7DSBCAPSZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer12SetFrequencyMWkZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9SetFormatMWPxS4core3sys7windows8mmsystem12WAVEFORMATEXZi@4 sound.obj(sound) Error 42: Symbol Undefined __D8sound18IDirectSoundBuffer9SetVolumeMWiZi@4
Re: Alias this member shadowed by imported function identifier?
On 5/27/16 9:33 AM, Johan Engelen wrote: The following code compiles with DMD 2.070, but not with 2.071: ``` module mod; import std.range; struct S { struct Inner { int unique_identifier_name; int tail; } Inner inner; alias inner this; auto works() { return unique_identifier_name; } auto fails() { return tail; // Line 22 // The workaround: return this.tail; } } ``` The 2.071 error is: tail.d(22): Error: template tail(Range)(Range range, size_t n) if (isInputRange!Range && !isInfinite!Range && (hasLength!Range || isForwardRange!Range)) has no type Is this because of the new import rules, or is it a bug? Thanks, Johan I believe in the new import rules, all module members should override any imported ones, unless the import is renaming (which is equivalent to aliasing into your local namespace the symbol). Now, the question here is, when does alias this kick in? I would say it should follow alias this before looking outside the module, so I say it's a bug. -Steve
Re: Why do some T.init evaluate to true while others to false?
On 5/27/16 11:49 AM, ArturG wrote: On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote: yes but i have to check for that when some one does Why? This is no different than if they set any of the other four billion possible values. What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense? float f; if(f) "why does this print".writeln; // it should not same for char char c; if(c) "why does this print".writeln; // it should not it works for most other types is there any reason why it doesnt work or couldnt work with floating points and character types? conversion to bool is not universally (val !is val.init) Why are you expecting it to be? Won't work for enums with first elements that are non-zero either: enum foo : int { bar = 1; } foo f; if(f) writeln("this will output too"); -Steve
Re: Benchmark Dlang vs Node vs Ruby
Why not to use distribute oprion? Dne 27. 5. 2016 17:35 napsal uživatel "yawniek via Digitalmars-d-learn" < digitalmars-d-learn@puremagic.com>: > On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: > >> Hi guys, >> >> In my journey of learning about D I tried to benchmark D with Vibe.d vs >> node with express and Ruby with Sinatra. >> >> And the results are pretty surprising. >> I have to admit that I though D was more faster than that. How is this >> even possible ? >> >> I am doing something wrong ? >> >> >> Here are the numbers with the project : >> >> https://github.com/llaine/benchmarks/blob/master/README.md >> > > you should: > - use this https://github.com/etcimon/ddb Postgres client > - fix your logic > - NOT use option distribute > - use LDC2 beta2 as compiler with release flag > - use neweset vibe.d version > > and then your results should be easily above 1000 rps > > >
Re: Alias this member shadowed by imported function identifier?
Hmm... I wouldn't expect this to work, but still worth to report in bugzilla.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 15:48:18 UTC, llaine wrote: On Friday, 27 May 2016 at 15:32:13 UTC, yawniek wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: [...] you should: - use this https://github.com/etcimon/ddb Postgres client - fix your logic - NOT use option distribute - use LDC2 beta2 as compiler with release flag - use neweset vibe.d version and then your results should be easily above 1000 rps Okay by just fixing my logic, I go up to 839.42 Req/Sec for 10 sec and 601.74 Req/Sec for 30sec which is pretty impressive! My other question here is, can I specify directly in dub the compiler I want to use? Something like this : dub -compiler=ldc|dmd ... Because I really want to try to reach 1000rps I've update my SQL dump with 100 entries and now and I have better results! Pretty amazing :) If you guys want to improve it feel free to PR !!!
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 15:28:42 UTC, Andrew Edwards wrote: Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and @12 decorations (would be __stdcall on C/C++ side) The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded. If you declare extern function with wrong calling convention, calling it can result in stack corruption. Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented. This struct is called COM interface, D has built-in support for them: https://dlang.org/spec/interface.html#com-interfaces
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 15:24:18 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote: yes but i have to check for that when some one does Why? This is no different than if they set any of the other four billion possible values. What do you mean? operation on float.nan gives you a float.nan so why does the shortcut evaluate to true and not false wouldnt that make more sense? float f; if(f) "why does this print".writeln; // it should not same for char char c; if(c) "why does this print".writeln; // it should not it works for most other types is there any reason why it doesnt work or couldnt work with floating points and character types?
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 15:32:13 UTC, yawniek wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md you should: - use this https://github.com/etcimon/ddb Postgres client - fix your logic - NOT use option distribute - use LDC2 beta2 as compiler with release flag - use neweset vibe.d version and then your results should be easily above 1000 rps Okay by just fixing my logic, I go up to 839.42 Req/Sec for 10 sec and 601.74 Req/Sec for 30sec which is pretty impressive! My other question here is, can I specify directly in dub the compiler I want to use? Something like this : dub -compiler=ldc|dmd ... Because I really want to try to reach 1000rps
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md you should: - use this https://github.com/etcimon/ddb Postgres client - fix your logic - NOT use option distribute - use LDC2 beta2 as compiler with release flag - use neweset vibe.d version and then your results should be easily above 1000 rps
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 15:18:38 UTC, llaine wrote: - And how can I minimize allocations? My previous post still allocates though, through that call to array at the end. I'm not sure how to completely remove all allocations (I'm not that familiar with vibe.d), but I strongly suspect it's possible. Someone else may know how. That said, it's a an optimization which should not be necessary in the general case. Only if you're doing something where there's tight maximum latency requirements (or when doing benchmarks ^^)
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 12:30:50 UTC, Guillaume Piolat wrote: On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote: OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate@12 --- errorlevel 1 Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and @12 decorations (would be __stdcall on C/C++ side) The thought never crossed my mind. Tried it and it works like a charm. Thanks to everyone who responded. notna: It is not really necessary to put the lib in the libs folder since it's being passed on the command line and available in the build directory. I will place it there eventually though. On other issue remains that I could not sort out: Once DirectSoundCreate() returns successfully, I need to call one of the function pointers in the struct but am at a loss of how to define it based on the interface presented. According the code, SetCooperativeLevel() can be called one of two ways, either via a template[1] or directly through the second parameter provided to and modified by SetCooperativeLevel(). I tried the two approaches below both inside and outside the struct but neither worked. // first approach struct IDirectSound { extern(C) HRESULT SetCooperativeLevel(HWND, DWORD); } // second approach alias setCooperativeLevel = HRESULT function(HWND, DWORD); setCooperativeLevel SetCooperativeLevel; It seemed pointless trying to recreate the template since above attempts did not expose the function signature which is necessary to get the template working. Any ideas? [1] https://gist.github.com/AndrewEdwards/560601a62ea890842ecac90bb41896a8#file-dsound-h-L248
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 15:04:31 UTC, llaine wrote: My level of D is really slow, so can you help me to improve this? :) Here's an alternative getCompanies. Untested so it may contain some mistakes. Company[] getCompanies() { auto conn = client.lockConnection(); immutable result = conn.execStatement("SELECT id, name from companies LIMIT 1", ValueFormat.TEXT); delete conn; import std.algorithm : map; import std.array : array; return result .rangify .map!(row => Company(row["id"].as!PGtext, row["name"].as!PGtext)) .array; }
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 15:19:50 UTC, ArturG wrote: yes but i have to check for that when some one does Why? This is no different than if they set any of the other four billion possible values.
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 15:07:50 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 14:56:28 UTC, ArturG wrote: float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln; You changed it to a value that isn't float.init, so of course it isn't going to match! float.nan and float.init are NOT the same thing. float.init is a kind of NAN, but not the same kind. yes but i have to check for that when some one does float.nan.checkThen!((f){ this fun should not run }); which should be the same as float.init.checkThen!((f){ this fun should not run });
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 15:11:32 UTC, Rene Zwanenburg wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md Could this line be the problem? https://github.com/llaine/benchmarks/blob/master/vibed/source/app.d#L30 You keep appending the db result to a class member, so the response size grows with every call. Additionally minimizing allocations should give a nice speed boost. As I said I'm sorry, my level in D is really low, so : - How can I not keep appending ? - And how can I minimize allocations?
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md Could this line be the problem? https://github.com/llaine/benchmarks/blob/master/vibed/source/app.d#L30 You keep appending the db result to a class member, so the response size grows with every call. Additionally minimizing allocations should give a nice speed boost.
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 14:56:28 UTC, ArturG wrote: float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln; You changed it to a value that isn't float.init, so of course it isn't going to match! float.nan and float.init are NOT the same thing. float.init is a kind of NAN, but not the same kind.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:59:44 UTC, yazd wrote: On Friday, 27 May 2016 at 14:46:47 UTC, llaine wrote: On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? All right after switching of psql client I had lower results actually ... Req/Sec 22.85 for 30 seconds. What are you using to do web if you don't user Vibe.d? Your code is not doing the same thing in the benchmarks. In D, you are appending 1 companies on every request, resulting in 1, 2, 3, companies in subsequent requests. My level of D is really slow, so can you help me to improve this? :)
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:46:47 UTC, llaine wrote: What are you using to do web if you don't user Vibe.d? I wrote my own web libraries starting back in ~2009ish (well before vibe.d existed) and still use them. The modules are in here: https://github.com/adamdruppe/arsd though I don't really support it for general audiences, you're basically on your own unless you have a specific question.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:48:19 UTC, Daniel Kozak wrote: On Friday, 27 May 2016 at 14:18:31 UTC, llaine wrote: On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? Yes it's that i'm routing to /companies to get the result, but let me change the psql library delete this routing and trying again. Yous should enable http://vibed.org/api/vibe.http.server/HTTPServerOption.distribute something like this: auto settings = new HTTPServerSettings; settings.port = 8080; settings.options |= HTTPServerOption.distribute; listenHTTP(settings, router); Hi, With this option I get the same results but something interesting is displayed on the binary output : core.exception.InvalidMemoryOperationError@src/core/exception.d(693): Invalid memory operation The code : https://github.com/llaine/benchmarks/blob/master/vibed/source/app.d
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:46:47 UTC, llaine wrote: On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? All right after switching of psql client I had lower results actually ... Req/Sec 22.85 for 30 seconds. What are you using to do web if you don't user Vibe.d? Your code is not doing the same thing in the benchmarks. In D, you are appending 1 companies on every request, resulting in 1, 2, 3, companies in subsequent requests.
Re: I wrote a function that accepts input ranges, and I get compile errors when passing an array
On Friday, 27 May 2016 at 14:54:30 UTC, pineapple wrote: I've encountered one remarkable difference: The phobos function accepts arrays and mine does not. add `import std.array;` i think to your module and it should make arrays ranges
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 14:48:59 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 14:43:47 UTC, ArturG wrote: if(value is typeof(value).init) ... that still requiers a special case for floating points, arrays and optionally empty string literals. Have you tried? That should work in all cases. float f; if(f is float.init) "float init".writeln; f = float.nan; if(f is float.init) "float nan".writeln;
I wrote a function that accepts input ranges, and I get compile errors when passing an array
I'm writing my own map function modeled after the one in phobos. (because I feel like it, that's why. good learning experience.) I've encountered one remarkable difference: The phobos function accepts arrays and mine does not. I understand why - I'm calling methods that arrays don't have - but what I don't understand is why the phobos function _does_ work. I haven't been able to find what in the phobos code accounts for iterables that aren't ranges. What am I missing? enum canMap(T) = isInputRange!(Unqual!T); auto map(alias func, Range)(Range range) if(canMap!Range){ return Mapping!(func, Range)(range); } struct Mapping(alias func, Range) if(canMap!Range){ alias URange = Unqual!Range; Range input; this(URange input){ this.input = input; } void popFront(){ this.input.popFront(); } @property auto ref front(){ return func(this.input.front); } static if(isBidirectionalRange!URange){ @property auto ref back(){ return func(this.input.back); } void popBack(){ this.input.popBack(); } } static if(isInfinite!URange){ enum bool empty = false; }else{ @property bool empty(){ return this.input.empty; } } static if(isRandomAccessRange!URange){ static if(is(typeof(URange.opIndex) == function)){ alias Index = Parameters!(URange.opIndex)[0]; }else{ alias Index = size_t; } auto ref opIndex(Index index){ return func(this.input[index]); } } static if(is(typeof(URange.opDollar))){ alias opDollar = URange.opDollar; } static if(hasLength!URange){ @property auto length(){ return this.input.length; } } static if(hasSlicing!URange){ static if(is(typeof(URange.opIndex) == function)){ alias SliceIndex = Parameters!(URange.opIndex)[0]; }else{ alias SliceIndex = size_t; } auto opSlice(SliceIndex low, SliceIndex high){ return typeof(this)(this.input[low .. high]); } } static if(isForwardRange!URange){ @property auto save(){ return typeof(this)(this.input.save); } } } version(unittest) import mach.error.unit; unittest{ import std.stdio; //import std.algorithm : map; // Works with this // no property 'popFront', etc for type 'int[]' writeln( [1, 2, 3].map!((item) => (item * item)) ); } Tangentially related question - Why does phobos use isInputRange!(Unqual!T) instead of just isInputRange!T? What's the functional difference here?
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 14:43:47 UTC, ArturG wrote: if(value is typeof(value).init) ... that still requiers a special case for floating points, arrays and optionally empty string literals. Have you tried? That should work in all cases.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:18:31 UTC, llaine wrote: On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? Yes it's that i'm routing to /companies to get the result, but let me change the psql library delete this routing and trying again. Yous should enable http://vibed.org/api/vibe.http.server/HTTPServerOption.distribute something like this: auto settings = new HTTPServerSettings; settings.port = 8080; settings.options |= HTTPServerOption.distribute; listenHTTP(settings, router);
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? All right after switching of psql client I had lower results actually ... Req/Sec 22.85 for 30 seconds. What are you using to do web if you don't user Vibe.d?
Re: Why do some T.init evaluate to true while others to false?
On Friday, 27 May 2016 at 09:25:55 UTC, Marc Schütz wrote: On Thursday, 26 May 2016 at 16:45:22 UTC, ArturG wrote: im just playing with this template[1] is there anything else i missed? (if you dont mind) it basically treats any T.init as false and skips the function/delegate and just returns type. [1] https://dpaste.dzfl.pl/d159d83e3167 If you just want to check whether something is equal to its type's .init value, use the `is` operator, which does a bitwise comparison: if(value is typeof(value).init) ... that still requiers a special case for floating points, arrays and optionally empty string literals.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 14:17:16 UTC, Adam D. Ruppe wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right? Yes it's that i'm routing to /companies to get the result, but let me change the psql library delete this routing and trying again.
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: I am doing something wrong ? So, the benchmark, the Ruby, and the JS all use the path to be / the D seems to use /companies (though I don't know vibe). Is that right?
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md The postgres library (dpq) that you're using doesn't use the event loop that vibe-d provides. Every call you are doing is blocking the whole server. Of course this is going to be slow. You can try using http://code.dlang.org/packages/vibe-d-postgresql.
Re: Benchmark Dlang vs Node vs Ruby
oooh, I wanna try my libs. Where's your database dump?
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:54:20 UTC, Vadim Lopatin wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md Probably node and Ruby cache PGSQL connection - keeping it open. Okay I'll manage to do it, but still the req/sec are pretty low ...
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md You should know: https://www.techempower.com/benchmarks/#section=data-r12=peak=json=ft4 Dlang is quite slow. I have no idea way, or how to improve it. But clear, is not that fast. Maybe for web related is slow. I'm more curious about more benchmarks :)
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:54:20 UTC, Vadim Lopatin wrote: On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md Probably node and Ruby cache PGSQL connection - keeping it open. How I'm suppose to do it ?
Re: Benchmark Dlang vs Node vs Ruby
On Friday, 27 May 2016 at 13:45:23 UTC, llaine wrote: Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md Probably node and Ruby cache PGSQL connection - keeping it open.
Benchmark Dlang vs Node vs Ruby
Hi guys, In my journey of learning about D I tried to benchmark D with Vibe.d vs node with express and Ruby with Sinatra. And the results are pretty surprising. I have to admit that I though D was more faster than that. How is this even possible ? I am doing something wrong ? Here are the numbers with the project : https://github.com/llaine/benchmarks/blob/master/README.md
Alias this member shadowed by imported function identifier?
The following code compiles with DMD 2.070, but not with 2.071: ``` module mod; import std.range; struct S { struct Inner { int unique_identifier_name; int tail; } Inner inner; alias inner this; auto works() { return unique_identifier_name; } auto fails() { return tail; // Line 22 // The workaround: return this.tail; } } ``` The 2.071 error is: tail.d(22): Error: template tail(Range)(Range range, size_t n) if (isInputRange!Range && !isInfinite!Range && (hasLength!Range || isForwardRange!Range)) has no type Is this because of the new import rules, or is it a bug? Thanks, Johan
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote: http://ftp.dlang.org/ctg/implib.html The above URL suggests that, on Windoze, I can create a D compatible lib from a dll file by issuing the command: [...] If you haven't done so, you need to copy your resulting LIB file to your standard LIBs folder, which under Windows_X86 should be: - C:\D\dmd2\windows\lib regards
Re: Request assistance binding to Windows dsound.{lib, dll}
Another possibility is to use -m32mscoff switch https://dlang.org/dmd-windows.html#switch-m32mscoff and use ms toolchain for linking with PSDK import libraries.
Re: Request assistance binding to Windows dsound.{lib, dll}
https://forum.dlang.org/post/kcr2vn$21i6$1...@digitalmars.com implib can work for extern(C), but is likely to fail even for them.
Re: Request assistance binding to Windows dsound.{lib, dll}
On Friday, 27 May 2016 at 12:26:19 UTC, Andrew Edwards wrote: OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate@12 --- errorlevel 1 Have you tried with extern(C) yet? extern(C) is for undecorated symbold extern(Windows) adds the _ and @12 decorations (would be __stdcall on C/C++ side)
Request assistance binding to Windows dsound.{lib, dll}
http://ftp.dlang.org/ctg/implib.html The above URL suggests that, on Windoze, I can create a D compatible lib from a dll file by issuing the command: implib /s dsound.lib dsound.dll The following file: sound.d === pragma(lib, "dsound") struct IDirectSound{}; alias LPDIRECTSOUND = IDirectSound*; extern(Windows) HRESULT DirectSoundCreate(LPGUID, LPDIRECTSOUND*, LPUNKNOWN); void main() { LPDIRECTSOUND directSound; DirectSoundCreate(null, , null); } compiled as such: dmd sound dsound.lib produces the output: OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sound.obj(sound) Error 42: Symbol Undefined _DirectSoundCreate@12 --- errorlevel 1 Obviously I'm doing something incorrectly but I'm unable to see it. Please shed some light. The only thing I can see is that IDirectSound8 is improperly declared. It is struct generated form an interface which I have now idea of how to bind to from D: https://gist.github.com/AndrewEdwards/560601a62ea890842ecac90bb41896a8#file-dsound-h-L214 Thanks, Andrew
Re: Testing array ptr for offset 0...
On Thursday, 26 May 2016 at 21:13:14 UTC, Era Scarecrow wrote: To do what I want currently it's something like... enum Size = 1024, Other = 128; Data[Size][Other] staticarray; //stack allocation Data[][] sliced = staticarray[]; scan(sliced, condition); void scan(ref Data[][] data, Condition cond) { int lengths[Size]; foreach(i; ...) { if (cond) data[i][lengths[i]++] = ... } //cleanup/shrink foreach(i, l; lengths) data[i] = data[i][0 .. l]; } Like this: static void rawlength(ref Data[] r, size_t len) { r = r.ptr[0..len]; } void scan(ref Data[][] data, Condition cond) { foreach(i; ...) { if (cond) data[i].rawlength = ... } }
Re: Testing array ptr for offset 0...
On Friday, 27 May 2016 at 09:18:47 UTC, Marc Schütz wrote: You can do that with arrays, too, without causing allocations: assert(slice.length < static_array.length); slice = slice.ptr[0 .. slice.length+1]; Of course that's unsafe, but your pointer magic certainly is, too. Initial impressions suggest it's actually slower. The multiple dereferences to do it since it's a 2d array...
Re: asm woes...
On Friday, 27 May 2016 at 10:14:31 UTC, Era Scarecrow wrote: inc dword ptr [EAX+Foo.x.offsetof]; So just tested it, and it didn't hang, meaning all unittests also passed. Final solution is: asm pure @nogc nothrow { mov EAX, this; add dword ptr [EAX+wideIntImpl.lo.offsetof], 1; adc dword ptr [EAX+wideIntImpl.lo.offsetof+4], 0; adc dword ptr [EAX+wideIntImpl.hi.offsetof], 0; adc dword ptr [EAX+wideIntImpl.hi.offsetof+4], 0; }
Re: asm woes...
On Friday, 27 May 2016 at 10:00:40 UTC, Era Scarecrow wrote: On Friday, 27 May 2016 at 09:51:56 UTC, rikki cattermole wrote: struct Foo { int x; void foobar() { asm { mov EAX, this; inc [EAX+Foo.x.offsetof]; } } } You have to reference the field via a register. This is good progress. Using the assembler doesn't have many documentation examples of how to do things Hmmm actually this is incorrect... void main() { import std.stdio; Foo foo = Foo(-1); writeln(foo.x); foo.foobar; writeln(foo.x); } -1 -256 It's assuming a byte obviously for the size. So this is the correct instruction: inc dword ptr [EAX+Foo.x.offsetof]; However trying it with a long and a qword shows it reverts to a byte again, meaning 64 bit instructions are inaccessible.
Re: asm woes...
On Friday, 27 May 2016 at 10:00:40 UTC, Era Scarecrow wrote: On Friday, 27 May 2016 at 09:51:56 UTC, rikki cattermole wrote: This is good progress. Using the assembler doesn't have many documentation examples of how to do things, guess the x[ESP] example was totally useless on the iasm page. Referencing EBP or ESP yourself is indeed dangerous. Not sure why the documentation would advise that. Using "this", names of parameters/locals/field offset is much safer.
Re: asm woes...
On Friday, 27 May 2016 at 09:51:56 UTC, rikki cattermole wrote: Me and p0nce solved this on IRC. struct Foo { int x; void foobar() { asm { mov EAX, this; inc [EAX+Foo.x.offsetof]; } } } void main() { import std.stdio; Foo foo = Foo(8); foo.foobar; writeln(foo.x); } You have to reference the field via a register. This is good progress. Using the assembler doesn't have many documentation examples of how to do things, guess the x[ESP] example was totally useless on the iasm page.
Re: asm woes...
On Friday, 27 May 2016 at 09:51:36 UTC, Guillaume Piolat wrote: On Friday, 27 May 2016 at 09:44:47 UTC, Era Scarecrow wrote: Nope, still hangs... We can't know why your code hangs if you don't post any code. Considering I'd have to include the whole of wideint.d, that is highly implausible to do. But already got a possible answer which I'm about to test.
Re: asm woes...
On 27/05/2016 8:20 PM, Era Scarecrow wrote: Well decided I should dig my hand in assembly just to see if it would work. Using wideint.d as a starting point I thought I would do the simplest operation I could do, an increment. https://github.com/d-gamedev-team/gfm/blob/master/integers/gfm/integers/wideint.d https://dlang.org/spec/iasm.html Most of my code was failing outright until I looked at the integrated assembler page, which TDPL doesn't go into at all. To access variables for example I have to do var[ESP] or var[RSP] to access it from the stack frame. Unintuitive, but sure I can work with it. So the code for incrementing is pretty simple... @nogc void increment() pure nothrow ++lo; if (lo == 0) ++hi; } That's pretty simple to work with. I know the assembly instructions can be done 1 of 2 ways. add lo, 1 adc hi, 0 OR inc lo jnc L1 //jump if not carry inc hi So I've tried. Considering the wideint basically is self calling if you want to make a larger type than 128bit, then that means I need to leave the original code alone if it's a type that's too large, but only inject assembly if it's the right time and size. Thankfully bits is there to tell us. So, add version @nogc void increment() pure nothrow { static if (bits > 128) { ++lo; if (lo == 0) ++hi; } else { version(X86) { asm pure @nogc nothrow { add lo[ESP], 1; adc hi[ESP], 0; } } else { ++lo; if (lo == 0) ++hi; } } } I compile and get: Error: asm statements cannot be interpreted at compile time The whole thing now fails, rather than compiling to do the unittests... Doing the inc version gives the same error.. asm pure @nogc nothrow { inc lo[ESP]; jnc L1; inc hi[ESP]; L1:; } Naturally it wasn't very specific about if I should rely on RSP or ESP or what, but since it's X86 rather than X86_64 I guess that answers it... would be easy to write the x64 version, if it would let me. So i figure i put a check for __ctfe and that will avoid the assembly calls if that's the case. So... version(X86) { @nogc void increment() pure nothrow { if (!__ctfe && bits == 128) { asm pure @nogc nothrow { add lo[ESP], 1; adc hi[ESP], 0; } } else { ++lo; if (lo == 0) ++hi; } } } else { //original declaration } Now it compiles, however it hangs the program when doing the unittest. Why does it hang the program? I have no clue. Tried changing the ESP to EBP just in case that was actually what it wanted, but doesn't seem to be the case. I can tell how I will be refactoring the code, assuming i can figure out what's wrong in the first place... Anyone with inline assembly experience who can help me out a little? 2 add instructions shouldn't cause it to hang... Me and p0nce solved this on IRC. struct Foo { int x; void foobar() { asm { mov EAX, this; inc [EAX+Foo.x.offsetof]; } } } void main() { import std.stdio; Foo foo = Foo(8); foo.foobar; writeln(foo.x); } You have to reference the field via a register.
Re: asm woes...
On Friday, 27 May 2016 at 09:44:47 UTC, Era Scarecrow wrote: On Friday, 27 May 2016 at 09:39:36 UTC, Era Scarecrow wrote: I suppose there's the requirement to have a register pointing to this, which then would be mov EAX, this, and then add lo[EAX], 1... Nope, still hangs... We can't know why your code hangs if you don't post any code. https://dpaste.dzfl.pl/4026d9e6d3c0
Re: asm woes...
On Friday, 27 May 2016 at 09:39:36 UTC, Era Scarecrow wrote: I suppose there's the requirement to have a register pointing to this, which then would be mov EAX, this, and then add lo[EAX], 1... Nope, still hangs...
Re: asm woes...
On Friday, 27 May 2016 at 09:22:49 UTC, Guillaume Piolat wrote: On Friday, 27 May 2016 at 09:11:01 UTC, Era Scarecrow wrote: Hmmm it just occurs to me I made a big assumption. I assumed that if the CPU supports 64bit operations, that it would be compiled to use 64bit registers when possible. I'm assuming this is not the case. As such the tests I was doing will probably be of little help _unless_ it was X86_64 code, or a check that verifies it's 64bit hardware? You have to write your code three times, one for version(D_InlineAsm_X86) version (D_InlineAsm_X86_64) and a version without assembly. If longs are emulated, then only X86_64 and without assembly would be considered, as there would be no benefit to doing the X86 version. If i can do it, the two will be identical, except for which stack register is used. (A lot of wasted space for so little to add). TBH I don't know how to access members in assembly, I think you shouldn't ever do that. It will depend heavily on the particular calling convention called. Just put these fields in local variables. The compiler will replace with the right register-indexed stuff. But honestly I doubt it will be any faster because on the other hand you mess with the optimizer. Hmmm tried it as you have it listed. Still hangs. Tried it directly with qword with and without [ESP], still hangs. The listed inline assembler here on Dlang says to use 'variableName[ESP]', which then becomes obvious it's a variable and even probably inserts type-size information as appropriate. Although I did it manually as you had listed but it still hangs. I suppose there's the requirement to have a register pointing to this, which then would be mov EAX, this, and then add lo[EAX], 1...
Re: Why do some T.init evaluate to true while others to false?
On Thursday, 26 May 2016 at 16:45:22 UTC, ArturG wrote: im just playing with this template[1] is there anything else i missed? (if you dont mind) it basically treats any T.init as false and skips the function/delegate and just returns type. [1] https://dpaste.dzfl.pl/d159d83e3167 If you just want to check whether something is equal to its type's .init value, use the `is` operator, which does a bitwise comparison: if(value is typeof(value).init) ...
Re: asm woes...
On Friday, 27 May 2016 at 09:11:01 UTC, Era Scarecrow wrote: Hmmm it just occurs to me I made a big assumption. I assumed that if the CPU supports 64bit operations, that it would be compiled to use 64bit registers when possible. I'm assuming this is not the case. As such the tests I was doing will probably be of little help _unless_ it was X86_64 code, or a check that verifies it's 64bit hardware? You have to write your code three times, one for version(D_InlineAsm_X86) version (D_InlineAsm_X86_64) and a version without assembly. In rare cases you can merge D_InlineAsm_X86 and D_InlineAsm_X86_64 versions. D provides unfortunately less support to write code that is valid in both compared to C++! This causes lots of duplication TBH I don't know how to access members in assembly, I think you shouldn't ever do that. It will depend heavily on the particular calling convention called. Just put these fields in local variables. void increment() { auto lo_local = lo; auto hi_local = hi; asm { add dword ptr lo_local, 1; adc dword ptr hi_local, 0; } lo = lo_local; hi = hi_local; } The compiler will replace with the right register-indexed stuff. But honestly I doubt it will be any faster because on the other hand you mess with the optimizer.
Re: Testing array ptr for offset 0...
On Thursday, 26 May 2016 at 22:47:02 UTC, Era Scarecrow wrote: On Thursday, 26 May 2016 at 22:15:42 UTC, ag0aep6g wrote: Sorry, I'm still lost. Why can't you do whatever you're doing in opOpAssign directly there, or in a free function? Does the pseudo-array contain any additional data? Would a wrapper around a built-in array not work? Well a few things at work. First the array is originally a static array, so I pass it as a slice; But if you pass it as a slice you get the entire length, and modifying the length requires either changing length or appending, both which may cause allocation (something I want to avoid). By making my own compatible structure I can manage the length and pointer directly and precisely. You can do that with arrays, too, without causing allocations: assert(slice.length < static_array.length); slice = slice.ptr[0 .. slice.length+1]; Of course that's unsafe, but your pointer magic certainly is, too.
Re: asm woes...
On Friday, 27 May 2016 at 08:20:02 UTC, Era Scarecrow wrote: Anyone with inline assembly experience who can help me out a little? 2 add instructions shouldn't cause it to hang... Hmmm it just occurs to me I made a big assumption. I assumed that if the CPU supports 64bit operations, that it would be compiled to use 64bit registers when possible. I'm assuming this is not the case. As such the tests I was doing will probably be of little help _unless_ it was X86_64 code, or a check that verifies it's 64bit hardware? Does this mean the 64bit types are emulated rather than using hardware?
Re: Operator overloading through UFCS doesn't work
On Thursday, 26 May 2016 at 06:23:17 UTC, Jonathan M Davis wrote: The difference is that it's impossible to do 10.opBinary!"+"(15), so if you're forced to do foo.opBinary!"+"(bar) to get around a symbol conflict, it won't work with built-in types. Well, that begs the question: Why don't built-in types define `opBinary`? That's just another arbitrary irregularity, isn't it.
Re: full copies on assignment
On Thursday, 26 May 2016 at 10:51:30 UTC, John Nixon wrote: On Wednesday, 25 May 2016 at 15:44:34 UTC, Marc Schütz wrote: On Tuesday, 24 May 2016 at 20:58:11 UTC, John Nixon wrote: On Tuesday, 24 May 2016 at 15:17:37 UTC, Adam D. Ruppe wrote: On Tuesday, 24 May 2016 at 14:29:53 UTC, John Nixon wrote: Or add an explicit constructor: struct CS { // ... this(const CS rhs) { this = rhs; } Unfortunately this results in "Error: cannot implicitly convert expression (rhs) of type const(CS) to CS'. Hmm... this is the full program that works for me: import std.stdio; struct CS { char[] t; this(const CS rhs) { this = rhs; } CS opAssign(const CS rhs) { writeln("CS.opAssign called"); this.t = rhs.t.dup; return this; } }; void test_fun(const ref CS rhs) { auto cs = CS(rhs); writeln("cs = ",cs); } void main() { CS rhs; rhs.t = "string".dup; test_fun(rhs); return; }
asm woes...
Well decided I should dig my hand in assembly just to see if it would work. Using wideint.d as a starting point I thought I would do the simplest operation I could do, an increment. https://github.com/d-gamedev-team/gfm/blob/master/integers/gfm/integers/wideint.d https://dlang.org/spec/iasm.html Most of my code was failing outright until I looked at the integrated assembler page, which TDPL doesn't go into at all. To access variables for example I have to do var[ESP] or var[RSP] to access it from the stack frame. Unintuitive, but sure I can work with it. So the code for incrementing is pretty simple... @nogc void increment() pure nothrow ++lo; if (lo == 0) ++hi; } That's pretty simple to work with. I know the assembly instructions can be done 1 of 2 ways. add lo, 1 adc hi, 0 OR inc lo jnc L1 //jump if not carry inc hi So I've tried. Considering the wideint basically is self calling if you want to make a larger type than 128bit, then that means I need to leave the original code alone if it's a type that's too large, but only inject assembly if it's the right time and size. Thankfully bits is there to tell us. So, add version @nogc void increment() pure nothrow { static if (bits > 128) { ++lo; if (lo == 0) ++hi; } else { version(X86) { asm pure @nogc nothrow { add lo[ESP], 1; adc hi[ESP], 0; } } else { ++lo; if (lo == 0) ++hi; } } } I compile and get: Error: asm statements cannot be interpreted at compile time The whole thing now fails, rather than compiling to do the unittests... Doing the inc version gives the same error.. asm pure @nogc nothrow { inc lo[ESP]; jnc L1; inc hi[ESP]; L1:; } Naturally it wasn't very specific about if I should rely on RSP or ESP or what, but since it's X86 rather than X86_64 I guess that answers it... would be easy to write the x64 version, if it would let me. So i figure i put a check for __ctfe and that will avoid the assembly calls if that's the case. So... version(X86) { @nogc void increment() pure nothrow { if (!__ctfe && bits == 128) { asm pure @nogc nothrow { add lo[ESP], 1; adc hi[ESP], 0; } } else { ++lo; if (lo == 0) ++hi; } } } else { //original declaration } Now it compiles, however it hangs the program when doing the unittest. Why does it hang the program? I have no clue. Tried changing the ESP to EBP just in case that was actually what it wanted, but doesn't seem to be the case. I can tell how I will be refactoring the code, assuming i can figure out what's wrong in the first place... Anyone with inline assembly experience who can help me out a little? 2 add instructions shouldn't cause it to hang...