Re: vectorization of a simple loop -- not in DMD?
On Monday, 11 July 2022 at 22:16:05 UTC, ryuukk_ wrote: I use D because DMD compiles my huge project in ~1 second (full clean rebuild) It is a competitive advantage that many languages doesn't have The other programming languages typically use an interpreter for quick iterations and rapid development. For example, Python programming language has CPython interpreter, PyPy Just-in-Time compiler and Cython optimizing static compiler (not perfect right now, but shows a lot of promise). D still has a certain advantage over interpreters, because DMD generated code is typically only up to twice slower than LDC generated code. If the x86 architecture stops being dominant in the future and gets displaced by ARM or RISC-V, then this may become a problem for DMD. But we'll cross that bridge when we get there.
Re: Unwrap variadic template into vararg of pointers of the same types
On Friday, 8 July 2022 at 12:48:20 UTC, Paul Backus wrote: On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote: The problem when i try to introduce variadic template, is i can't seem to understand how to unwrap the parameter as pointer type T -> T* ```D struct Includes(Args...) { alias args = Args; } void view_it(Includes)(void function(entity_t, Includes.args* ) cb) { // do stuff } ``` I get the following: ```Error: cannot have pointer to `(EEntityRemoved)``` You can use [`std.meta.staticMap`][1] to make each type into a pointer individually: ```d import std.meta; alias Args = AliasSeq!(int, string, double); struct Includes { alias args = Args; } struct entity_t {} alias PointerTo(T) = T*; void view_it(void function(entity_t, staticMap!(PointerTo, Includes.args) ) cb) { // do stuff } ``` However, this will probably not work very well in your original code where `view_it` is a template, because the presence of `staticMap` in the parameter list will prevent the compiler from automatically deducing the template parameters. So, in this case, I think a better solution is to make the type of the callback fully generic, and use a template constraint to enforce your requirements: ```d import std.meta: allSatisfy; import std.traits: isPointer; void view_it(Callback)(Callback cb) if ( is(Callback == void function(entity_t, Args), Args...) && allSatisfy!(isPointer, Args) ) { // do stuff } ``` [1]: http://phobos.dpldocs.info/std.meta.staticMap.html Looks like my previous message did not get sent, i might have pressed on the wrong button Thanks for the snippet, i ended up copying the code from the imports, since importing the modules tanks my compile speed Although i'd prefer not rely on generic callback since i want to keep code completion, so i'll have to dig a little more, but that's for later, the solution works for now
Re: vectorization of a simple loop -- not in DMD?
On Monday, 11 July 2022 at 21:46:10 UTC, IGotD- wrote: On Monday, 11 July 2022 at 18:19:41 UTC, max haughton wrote: The dmd backend is ancient, it isn't really capable of these kinds of loop optimizations. I've said it several times before. Just depreciate the the DMD backend, it's just not up to the task anymore. This is not criticism against the original purpose of it as back in the 90s and early 2000s it made sense to create your own backend. Time has moved on and we have LLVM and GCC backends with a lot of CPU support that the D project could never achieve themselves. The D project should just can the DMD backend in order to free up resources for more important tasks. Some people say they like it because it is fast, yes it is fast because it doesn't do much. I use D because DMD compiles my huge project in ~1 second (full clean rebuild) It is a competitive advantage that many languages doesn't have LDC clean full rebuild ``` $ time dub build -f --compiler=ldc2 Performing "debug" build using ldc2 for x86_64. game ~master: building configuration "desktop"... Linking... real0m18.033s user0m0.000s sys 0m0.015s ``` LDC incremental ``` $ time dub build --compiler=ldc2 Performing "debug" build using ldc2 for x86_64. game ~master: building configuration "desktop"... Linking... real0m17.215s user0m0.000s sys 0m0.000s ``` DMD clean full rebuild ``` $ time dub build -f --compiler=dmd Performing "debug" build using dmd for x86_64. game ~master: building configuration "desktop"... Linking... real0m1.348s user0m0.031s sys 0m0.015s ``` DMD incremental ``` $ time dub build --compiler=dmd Performing "debug" build using dmd for x86_64. game ~master: building configuration "desktop"... Linking... real0m1.249s user0m0.000s sys 0m0.000s ``` The day DMD gets removed is the day i will good a different language I want to thank Walter for maintaining DMD the compiler, and making it incredibly fast at compiling code Release perf can't beat LLVM and its amount of optimizations, but the advantage is it allows VERY FAST and QUICK iteration time, it is ESSENTIAL for developing software
Re: vectorization of a simple loop -- not in DMD?
On Monday, 11 July 2022 at 18:19:41 UTC, max haughton wrote: The dmd backend is ancient, it isn't really capable of these kinds of loop optimizations. I've said it several times before. Just depreciate the the DMD backend, it's just not up to the task anymore. This is not criticism against the original purpose of it as back in the 90s and early 2000s it made sense to create your own backend. Time has moved on and we have LLVM and GCC backends with a lot of CPU support that the D project could never achieve themselves. The D project should just can the DMD backend in order to free up resources for more important tasks. Some people say they like it because it is fast, yes it is fast because it doesn't do much.
Re: vectorization of a simple loop -- not in DMD?
On Monday, 11 July 2022 at 18:15:16 UTC, Ivan Kazmenko wrote: Hi. I'm looking at the compiler output of DMD (-O -release), LDC (-O -release), and GDC (-O3) for a simple array operation: ``` void add1 (int [] a) { foreach (i; 0..a.length) a[i] += 1; } ``` Here are the outputs: https://godbolt.org/z/GcznbjEaf From what I gather at the view linked above, DMD does not use XMM registers for speedup, and does not unroll the loop either. [snip] Specifying a SIMD capable target will reveal an even wider gap in capability. (LDC -mcpu=x86-64-v3 or gdc -march=x86-64-v3).
Re: vectorization of a simple loop -- not in DMD?
On Monday, 11 July 2022 at 18:15:16 UTC, Ivan Kazmenko wrote: Hi. I'm looking at the compiler output of DMD (-O -release), LDC (-O -release), and GDC (-O3) for a simple array operation: ``` void add1 (int [] a) { foreach (i; 0..a.length) a[i] += 1; } ``` Here are the outputs: https://godbolt.org/z/GcznbjEaf From what I gather at the view linked above, DMD does not use XMM registers for speedup, and does not unroll the loop either. Switching between 32bit and 64bit doesn't help either. However, I recall in the past it was capable of at least some of these optimizations. So, how do I enable them for such a function? Ivan Kazmenko. How long ago is the past? The godbolt.org dmd is quite old. The dmd backend is ancient, it isn't really capable of these kinds of loop optimizations.
vectorization of a simple loop -- not in DMD?
Hi. I'm looking at the compiler output of DMD (-O -release), LDC (-O -release), and GDC (-O3) for a simple array operation: ``` void add1 (int [] a) { foreach (i; 0..a.length) a[i] += 1; } ``` Here are the outputs: https://godbolt.org/z/GcznbjEaf From what I gather at the view linked above, DMD does not use XMM registers for speedup, and does not unroll the loop either. Switching between 32bit and 64bit doesn't help either. However, I recall in the past it was capable of at least some of these optimizations. So, how do I enable them for such a function? Ivan Kazmenko.
Re: Background thread, async and GUI (dlangui)
On Sunday, 10 July 2022 at 09:15:59 UTC, Bagomot wrote: Based on Thread, I managed to do what I intended. I have not yet been able to figure out how to do the same through the Task. Here in the example, when you click on the Start button, a worker is launched that updates the progress bar. ... Do you have any suggestions how to do it more beautifully and not through the Thread? In particular, I would like to see the comments of the dlangui developers (@GrimMaple). Since you've already used `executeInUiThread` you can now just move your Thread.run() implementation to a free function and run it using task instead. `executeInUiThread` will ensure that passed delegate will be called in UI thread making it safe to call from another thread or task. Not sure about default widgets, but in some cases for your custom properties you might need to `invalidate()` widget to trigger redraw. Anyway you will need a reference to your widget to update progress bar value, options are: - It can be done in place where you start your task (e.g. inside button click event, delegates can access call site scope) - get widget reference directly by using `getWidgetById("WIDGET_ID")` (or how it was called, though you will need to assign ID to your progress bar and remember it) - use signal-slot mechanism (you still need widget reference to bind events) btw, have you tried googling this forum? I think there was exact same question with curl & dlangui a year or two ago, maybe it has an answer or at least tips you need? Anyway for curl notify progress delegate you can just do it inside that delegate using `executeInUiThread` there. like in example here https://dlang.org/library/std/net/curl/curl.on_progress.html adjusting to somewhat above will now look like (not tested) ```d // download button click event void downloadbutton_Click() { auto progressBar = (get progress bar reference); Curl curl; curl.initialize(); curl.set(CurlOption.url, "http://dlang.org";); curl.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) { // even though onProgress can be run in another thread this delegate will be run on next UI tick executeInUiThread( (){ progressBar.setProgress(dlnow/dltotal * 100); } ); return 0; }; curl.perform(); } ```
Re: Is there any implementation of a 128bit integer?
On Monday, 11 July 2022 at 02:49:52 UTC, Steven Schveighoffer wrote: So here is what happened: 1. User found an old thread (2019) asking if there was a 128-bit integer. 2. User noticed that there's a new implementation for 128-bit integers. 3. User replied to the thread indicating that there is an actual implementation now. 4. D forum software prompted user to create a new thread because it's really old. 5. The post you see above. Steven is right, it's actually a vicious circle! Because as long as we can't add 1 to ulong.max effortlessly (I guess it's called front end?), these discussions will continue... SDB@79
Re: How to obtain Variant underlying type?
On Monday, 11 July 2022 at 06:59:32 UTC, anonymouse wrote: I did search for a better solution and came across... https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html I like it! It's been a good collaboration... ```d import std.variant; auto generate(T)(size_t x, size_t y) { T[][] result; ubyte[] arr = new ubyte[x * y * T.sizeof]; size_t m = y * T.sizeof; foreach (i; 0 .. x) { size_t n = i * m; result ~= cast(T[])arr[n .. n + m]; } return result; } size_t[] shape(Variant v) { typeof(return) dims; while (cast(TypeInfo_Array) v.type !is null) { dims ~= v.length; v = v[0]; } if (!dims.length && v.length) { dims ~= v.length; dims ~= 0; } return dims; } void main() { foreach(x; 1..100) { foreach(y; 1..100) { auto test = Variant(generate!int(x, y)); assert(shape(test) == [x, y]); } } } ``` SDB@79
Re: How to obtain Variant underlying type?
On Monday, 11 July 2022 at 05:41:40 UTC, jfondren wrote: Oh, sorry. I didn't defend the code in any way because I assumed that the exceptional design would be seen as obviously bad (and that someone else would dig harder in order to find a better solution). And you were right. I did search for a better solution and came across [1]. Although I was having some issues adapting it for my use case, Paul Backus' follow-up clarified the issue. This is what my naive brain led to before reading this response. ```d size_t[] shape(Variant v) { typeof(return) dims; while(cast(TypeInfo_Array) v.type !is null) { dims ~= v.length; v = v[0]; } if(!dims.length && v.length) { dims ~= v.length; dims ~= 0; } return dims; } ``` Didn't see the bugs that would occur when a scalar or empty array was passed because I hadn't tested for them. if (!v.length) break; Pure gold! Bugs are eliminated, and the code is shorter. Thank you. --anonymouse [1] https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html