What LDC flags should be used to get the fastest executable on Windows?

Preetpal preetpal.sohal at gmail.com
Sat Mar 6 15:54:29 UTC 2021


On Saturday, 6 March 2021 at 14:56:00 UTC, Dennis wrote:
> On Saturday, 6 March 2021 at 13:45:42 UTC, Preetpal wrote:
>> I am kind of skeptical that this problem is 
>> performance-related as well but based on the decreased number 
>> of times that this problem occurred during my usage of the C 
>> version of program versus the D version that was not compiled 
>> with as aggressive optimization flags, it suggests that this 
>> is a performance problem.
>
> Have you compared your C version with and without optimization 
> flags?
> If that makes a difference, I think it's a race condition. 
> Though optimization flags might change the timing and mask away 
> the issue, it doesn't really solve the problem.
> A performance problem would be if your hook function actually 
> took near 300 ms to complete, but that doesn't seem the case 
> here.

Well in this instance, the callback is not called from different 
threads so you wouldn't have to worry about race conditions. 
According to the documentation 
(https://docs.microsoft.com/en-us/windows/win32/winmsg/lowlevelkeyboardproc): "This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook."

In this instance, I think I jumped to conclusions too early. 
There is indeed a bug in the program I wrote and by exploiting 
it, I can trigger the error on command in the conditional in my 
installed hook that deals with the type of message received.

else if(wParam == WM_KEYUP || wParam == WM_SYSKEYDOWN)

The second part of || test should be "wParam == WM_SYSKEYUP" 
instead of "wParam == WM_SYSKEYDOWN". According to the 
documentation 
(https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeyup), the WM_SYSKEYUP is triggered when keys are released when the ALT key is held. So by releasing any modifier when the ALT key wass held, the internal state of the program would be corrupted since the program would miss the release of that modifier key. The number of times that I probably encountered the issue in my program was purely a function of the order in which I was releasing keys (and based on what programs I was using, for example, Emacs) and not due to the number of the times the hook was timing out since due to it being slow.


>> Well I created the following test program on 
>> https://godbolt.org to see what kind of difference __gshared 
>> makes:
>
> I didn't suggest __gshared because it is faster, I suggested 
> because I don't know which thread calls your callback function. 
> If SetWindowsHookEx makes the calls to the callback from 
> different threads, then different instances of your variables 
> will be read / written to. So maybe Thread A sets shiftPressed 
> = true, and Thread B sets shiftPressed = false, and then Thread 
> A still reads shiftPressed = true when executing 
> detectAndActivateShortcut.

Another conclusion I made too early was assuming that __gshared 
is "faster" than using "thread-local storage" based on the number 
of instructions that the compiler generated (I don't know the 
actual cost of the operations (time-wise) to access/write to 
global variables with or without them being annotated __gshared. 
I have added to __gshared to the global variables my D version of 
the program so that it more closely matches the C version.

I have updated both of my versions of the programs with the fix.


More information about the digitalmars-d-ldc mailing list