Closed dragoon231 closed 1 year ago
Yea his method works using RWEverything in bat file, you just need to know the right ADDRESS to modify.
I built an automated script for this, but I am unable to test since I am on win11 22h2 and rw is not working.
Any way to confirm that the implementation is correct?
I am also looking for information about AMD Controllers, if it's the same way as intel or works differently.
If @BoringBoredom were able to help on this.
i don't seem to be able to see the "changes" when moving the mouse around
Try checking the next page. It's not always on the first one.
Any way to confirm that the implementation is correct?
It won't always be @ 2024. You'll need to figure out the exact location automatically.
I am also looking for information about AMD Controllers
I don't own an AMD system, so I can't help you with that.
Right, that's what I wanted to know, is there any pattern or way you might know to find that exact location, like you did as memory range left side being part of the address?
What is that exact location anyways?
@BoringBoredom @djdallmann
Edit:
After reading it better, If I am not missing anything, what is missing is, find the value from the word16bit 18hex position in the device, add(+) 24 to it and add(+) the value to the left side memory range value, that would be the address.
Is that 24h Intel only?
If @djdallmann steps are correct/accurate, then both videos on the internet are giving bad/incomplete instructions.
https://www.youtube.com/watch?v=mAgHhwNGmhg https://www.youtube.com/watch?v=eUgh_orZfMY
Nevermind, I was able to somewhat handle the issue for Intel, if anyone care to test / check and review. To know if it's correct and accurate.
I still dont have any information for AMD. I only know that it doesnt seem to be correct, since all I get are zeroes if I do the steps.
https://forums.blurbusters.com/viewtopic.php?f=10&t=11863&start=40
@BoringBoredom @djdallmann
@amitxv You seem to know a bit about these stuff, maybe you can help.
I updated this page with a guide since the one in this repository is partially incorrect. Runtime Register Space Offset
is 32 bits instead of 16 bits and located at +0x18 instead of +18 (the red number in RWE is a decimal, not hex). It was just a coincidence that both values were 0x2000 in that specific case.
Nice, ok, so, based on the updated guide
First step from rweverything seems feasible if the value, in the case of the screenshot (0x2000) will always stay at the first 32bit position.
Second step from the previous step value, add 0x24 and (32 * 0) to it. Does it mean that will always go to the proper value in the table?
Meaning, should the total go straigth at the first position or correct value itself in whatever position the table?
Because it seems you selected the 128 position value, but you didnt add (32 * 0) to the starting address.
Otherwise I would need more steps to find the proper address that is predictable in a way. Because given the instructions doesnt seem predictable, it seems you found the value after looking for it given the address + 0x24.
Did I misunderstood anything? @BoringBoredom
I need details because I understand nothing about this, I am just trying to build a script that automate the process.
(32 0) is Interrupter 0, (32 1) is Interrupter 1, etc. In that example, the mouse was on Interrupter 4 (32 * 4). You either have to set all IMOD registers to 0 or figure out a way to automatically determine which one is responsible for the mouse.
Right, but what I didnt understood yet is, in the last RW screenshot, you selected the 128 position with value 0x074B0FA0
, is that the exact (total) value (and the address to be changed) of Runtime Base + 0x24 + (32 * 4 (or 0, doesnt matter))
or it's a position you had to go looking for manually?
@BoringBoredom
Edit: Could be that you still use (Runtime Base + 0x24) as starting address and then you add+ (32 * interruptor) which would equal to 0x074B0FA0?
I have no idea how I would determine which one is responsible, probably need to go through them all. At least this way there would be a chance of working with many different devices, maybe even AMD.
But now thinking, there are many different controllers beyond Intel and AMD, I suppose I will just use the same method for them all, since no way to find information about all of them. Unless someone with proper understand provide specific information or a PR.
Wow, I see, in every interrupt, from the first position, it repeats itself every 2 lines, but the correct value will have the end value of the repeated value, but something different for the first 4 digits. If that is correct, then it's predictable.
So total of 2048 lines to be dumped and parsed through, to find the right interruptor and value in it. Also there seem to be 7 32-bit positions per interruptor.
You said that this 0FAO is what I want, but that is to find out the repeating pattern, right?
Still the 0x074B0FAO is the value/address I would use with RWEverything?
@BoringBoredom
Edit: Is the pattern going to repeat itself for 1023/4 times, that is certain?
Because there are other repetitions there, but some interruptors do not have the repetition in it.
Maybe it's always the first position at the at the interruptor?
Or maybe the address is actually the 4 digits hex?
If you are able to answer all these questions, I think it could be enough to start working on the proper solution.
After trying this out myself, the first value from * 0, kept changing even if I was not moving the mouse, I have the refresh interval very low, either way.
0xFC300000 = 4231004160
00000000FC300018 had first position 0x000004C0 = 1216
4231004160 + 1216 = 4231005376 = 0xFC3004C0
4231005376 + (32 * 1) = 0xFC3004E0
I saw the 0FA0, but no predictable pattern like in your screenshot.
Another problem, it seem the left side of the memory range, comes as 8 digits hex, not 16 when fetching through powershell. But given what you had done, all 16 were used. Here they cut from the first non-zero value, I wonder if they do the same in your case.
If you could check in powershell: Get-CimInstance -ClassName Win32_DeviceMemoryAddress | Select Name
Also given the screenshots, it seems that each interruptor have 8 positions and not 7, like in your sreenshot. Why in your screenshot, the first interruptor had 7 positions while the rest, 8? But when doing the actual calculation, it's clearly different.
32 0
32 1
I suppose I am unable to continue unless these questions are answered.
Everything you need to know is explained in the screenshots of the xHCI documentation. Take your time to read and understand it, otherwise you won't understand what I was talking about in my earlier posts.
Sure, but what I have been trying to get is understand certain details and as to find a pattern that is predictable so it can be coded.
I see you updated the guide again, thanks, you said to test, change last 4 values of a 32bit value to FA00, but what would that result in? Afaik there is nothing to check against that other than visual, unless there is a way to get a result from that in code, it's still just manual and visual instruction.
Top left number, in your case, that seems like a array memory position value, what do you mean add to the address, what address? It's a bunch of unclear details, it's expecting you to know a bunch before, and not giving details as if I you know nothing.
Edit:
Here is what I will do, I will code all the way to the part where the interruptors are from (0..1023), formatted into an array, containing it's top left position (4 by 4), the first interruptor having 7 positions.
@{Value = "00000000", TopLeftPosition = "0", Line = "00", Interruptor = "0"}
This is as far as I know that is possible, beyond this, not yet figured out, code wise.
I implemented the part I told I would, what remains now is find a pattern that is codeable to find the address, given all the interruptors 32bit values, if that is even possible.
Anyone whom might be interested, feel free to review and maybe even finish and implement what remains. It should be a decent clean implementation, easy to understand.
@BoringBoredom @amitxv
I had a brief look at your script and it seems overly complicated, you should be able to disable IMOD with a lot less lines than what you have. I would like to try out of interest, what method are you using to read the value at a given address in general?
What parts are overly complicated?
Current solution is only built given updated instructions from BoringBoredom. It's about finding the right address in between all 1024 interrupters. Considering that, unless new information comes up for an easier way, the current implementation should be simple and not complicated.
It's built to have all the addresses from all interrupters, what is missing is the actual feasible way to go through all the addresses and find out the actual correct one. Haven't figured that out yet. There are information, but it expect to be visual, what I want is a predictable way to find through code.
Regarding my question, I was wondering as to how you are reading addresses. You can read addresses from CLI with:
.\RW.exe /Command="R32 <address>" /Stdout
For determining the amount of interrupters, I think you can count the amount of IRQs the device is using but i'm not totally sure so don't quote me on that. Everything is the same for AMD, I tested it on another system.
https://www.amd.com/system/files/TechDocs/51192_Bolton_FCH_RRG.pdf
Sure, you can, but the address could be anywhere in any position from / in any interrupter. I then dumped all interrupters, parsed through, if there is a way to go through and compare them all to find the proper pattern as to identify the right address, then what I did would facilitate it.
Good to know about AMD, there are a bunch of other besides Intel and AMD, will use the same implementation for them all.
Regarding the answer to your question, based on the updated instructions by BoringBoredom + discussion here, I reach the right starting address and dumped all interrupters starting from the first (0). https://github.com/dougg0k/gaming_os_tweaker/blob/main/scripts/optional_helpers/interrupt_moderation_usb.ps1#L140
Then I parse all that data to be easy to use later, if possible, find a pattern that would help identify the right address automatically. https://github.com/dougg0k/gaming_os_tweaker/blob/main/scripts/optional_helpers/interrupt_moderation_usb.ps1#L165
What is missing is the part to identify the address betwen them all https://github.com/dougg0k/gaming_os_tweaker/blob/main/scripts/optional_helpers/interrupt_moderation_usb.ps1#L200
So, unless new info comes up for an easier way, that's what I have now.
As for your code quote, I know https://github.com/dougg0k/gaming_os_tweaker/blob/main/scripts/optional_helpers/interrupt_moderation_usb.ps1#L148 https://github.com/dougg0k/gaming_os_tweaker/blob/main/scripts/optional_helpers/interrupt_moderation_usb.ps1#L155
If anyone know any pattern that would help identify the address data wise, then that would be the solution to the problem.
Not if it's changing when mouse are moving (that is not possible to see data wise). Only visually and in realtime.
@BoringBoredom @amitxv
I found this tool https://desowin.org/usbpcap/tour.html maybe it could help, it has a cmd version, but it seems to depend on wireshark.
I wont spend more time on this, unless someone provide something that would help.
Apologies, I didn't see that you included the snippet in your script.
Without determining the amount of interrupters, it is difficult to determine how many addresses to iterate over to disable IMOD for.
Not if it's changing when mouse are moving (that is not possible to see data wise). Only visually and in realtime.
You could check whether the IMOD counter is > 0.
No problem.
Given the docs there are 1024 interrupters. So will always iterate through them all, per controller.
But there are many left side values that are higher than 0, doesnt mean it's the actual correct hex (address) / position.
@amitxv
Accordingly to this SS https://github.com/djdallmann/GamingPCSetup/issues/12#issuecomment-1612028115
First interrupter has 7 32-bit positions, while every other after, have 8. All have been dealt with in parsing. If there is a pattern in between them all as to find the address or at least considerable reduce the possible choices, the parsed data would help. That red value on the top left are the position, and it also been dealt with in parsing.
Data has been built, all we need is a predictable way to differentiate between all the values in the interrupters, if there is even a way.
It's not in my domain of knowledge, so as I have said, it will depend on someone else providing relevant information.
The docs mention that there can be up to 1024 interrupters, meaning there may not be 1024. I haven't looked into this that much but I don't think assuming there are always a fixed amount of interrupters is a good idea because you may be spilling into another address space in case the space is dynamic. If it is fixed then I guess it is fine but as I said, haven't looked into it that much.
The Interrupter logic consists of an Interrupter Management Register, an Interrupter Moderation Register, and the Event Ring Registers. A one to one mapping is defined for Interrupter to MSI-X vector. Up to 1024 Interrupters are supported.
On the other hand, the AMD docs mention that there can be up to 8 interrupters. You can't really continue without determining the amount of interrupters to disable IMOD for.
First interrupter has 7 32-bit positions, while every other after, have 8
They're all 8x4 bytes.
the address could be anywhere in any position from / in any interrupter
The IMOD register is always in the same spot within an interrupter: Runtime Base + 0x24 + (32 * interrupter index)
The docs mention that there can be up to 1024 interrupters, meaning there may not be 1024. I haven't looked into this that much but I don't think assuming there are always a fixed amount of interrupters is a good idea because you may be spilling into another address space in case the space is dynamic. If it is fixed then I guess it is fine but as I said, haven't looked into it that much.
I see, so that just something else that we would need to know how to differentiate or try handle per manufactor, because there are others other than Intel and AMD.
They're all 8x4 bytes.
Oh, I see.
The IMOD register is always in the same spot within an interrupter: Runtime Base + 0x24 + (32 * interrupter index)
Right. Calculation will lead straight to the address. But what are this Default Value: Field dependant
?
I suppose I should change that thought about trying to find patterns, fetch only based on the calculation and based on the quantity of interrupters, for now Intel being 1024 and AMD 8, unless there is a way to know per device the correct amount.
It's done, if anyone care to review and test if it's disabling the right addresses. Because it will disable them all, since there is no way to know which one are the correct, code wise.
What remains would be to have a way to identify the actual amount of interrupters.
@BoringBoredom @amitxv
You left this in your updated guide, now more questions. @BoringBoredom
To test whether it's the correct location, set the IMOD Interval (last 4 values) to FA00 (62.5 Hz).
Supposely I try every interrupter address and set the last 4 values as FA00
, how would that tell me that is the correct one? I mean using something like RWEverthing.
What (62.5Hz) even means in this context? Like I said, I know nothing, your guide expects you to know so.
The red number in the top left of the table is a decimal. Convert it to a hexadecimal before adding it to your address.
Wait, so the position number needs to be in the address, but doesnt seem part of the calculation, can you explain this?
As mentioned before, you can't assume that there will be a fixed amount of interrupters. For example, there is nothing at interrupter 1023 on my system. I wouldn't be comfortable with a script modifying random addresses.
I understand, If you read my comment above
What remains would be to have a way to identify the actual amount of interrupters.
If you or someone else are able to provide an way to identify the correct address and not apply disable through them all or provide a way to identify the correct amount of interrupters in a device, that would solve the problem.
Could there be a pattern that would identify the interrupts in sequence? Like if nothing in an address, means there are no interrupters beyond that point? @amitxv
If this were to be correct, then the memdump would actually be useful as to identify the amount of interrupters.
Found a way to get interrupters count, but only through windbg. https://learn.microsoft.com/pt-br/windows-hardware/drivers/debugger/-usb3kd-xhci-capability
Interrupt interval directly linked to usb bus?! https://docs.rs/usb-device/latest/usb_device/bus/trait.UsbBus.html
So 0xFA0 reset / default the interval, and there can be multiple instances of it if I didnt misunderstood. https://docs.xilinx.com/r/en-US/am012-versal-register-reference/IMOD_0-USB2_XHCI-Register
Bitrange 15:0 what does it mean, where it fit in this context? Here it says 8 registers. https://edc.intel.com/content/www/us/en/design/publications/13th-generation-core-processor-datasheet-volume-2-of-2/interrupter-moderation-imod0-offset-2024/
PciInterruptCount - But in usb viewer it's always 1. So, might not be this one. https://learn.microsoft.com/en-us/windows/win32/api/usbuser/ns-usbuser-usb_bus_statistics_0
It might be as @BoringBoredom said, I should just check for FA0
at the end of the value, if the left side of it are not zeroes, then it's the correct value?
Because even if the default IMODC are (0x0), but it keeps changing as you move the mouse, then, 0x0000FA0
should not
be correct.
Oh, but 0xFA0
are 4000 in decimal, the default value used.
https://www.overclock.net/threads/usb-polling-precision.1550666/page-61#post-28580928
Though that is on W7 only, means a different value for W8.1 and Win10, no info for Win11.
4000 (0xFA0) which is 1ms (250ns * 4000), for W8.1 and W10 it is set to 200 which is 50us
So, 250ns * 200 for Win10, 200 eq 0x00C8
, would that address be IMODI for Win10?
I need information when you run the script in Win7, is it going through Interrupters that end with 0xFA0? What about on Win10?
So, after all this, I checked, the value I get in Win11 from R32 SumCapabilityPlusRuntime are 0x04C0
and after summing to 0x24
it goes to 0x04E4
. This says or I am doing something wrong, or in Win11 are different, and or I should just in fact dump every value and go through them all accordingly to the OS.
What do you think? @BoringBoredom @amitxv
I temporarily disabled imod, if you guys could run the script and see what values are you getting. If is correct FA0 or something else. Maybe do a review in the script, that would help.
What has this got to do with IMOD? https://github.com/dougg0k/gaming_os_tweaker/blob/2c6ed3295e2ed539d9c5b5aa7fdf9b0fa3186b3c/scripts/optional_helpers/interrupt_moderation_usb.ps1#L108-L114
On another note, nobody has been able to demonstrate whether that actually does anything.
That is just meant to give irq priority to usb controlllers. An attempt to help increase responsiveness of mouse and keyboards. Though it could be more specifically set, I suppose, like to, only controllers that have mouse and keyboard plugged in.
I might refactor that later to the interrupt affinity auto script instead.
Some good info https://superuser.com/questions/456459/computer-architecture-are-usb-keyboards-less-responsive-due-to-narrow-irq-range
Accordingly to what is written, if that were to improve something it would be minor, in the microseconds (us). Which seems like somewhat what interrupt moderation interval effect does in certain OS.
That doesn't contain information for those registry entries. They have been polluting the internet for a while and a lot of people seem to use them without real evidence that it has any effect so I was wondering whether someone finally had any. On the other hand, Windows Internals specifies that DevicePriority
changes IRQ priorities which can I believe can be verified in WinDbg.
Yeah. Correct.
But from what I see they have different purposes, but both are able to affect devices. Where one is for IRQ (not only devices) and the DevicePriority are for devices only.
I use DevicePriority in some choices I did in this other automated script.
Some devices have multiple IRQs, not sure if DevicePriority affect them all or not, if they have different implementations for devices.
So, I guess it somewhat make sense to be in this script too, since someone might not use both of the scripts.
As for your affirmation on nobody being able to demonstrate, if the changes only are microseconds, most would probably not be able to truly do, unless in a very well built testing scenario to be able to trully tell if these would make any difference. Not when something else unknown could cause some effect that would disrupt small results like this one.
Plus, it would probably be even more difficult in a non tweaked scenario, where there would be many unknown parts running. But in a tweaked scenario it could have different effects, since other tweaks could end up unintedily affect the results.
Too small numbers to be easily able to know difference.
https://superuser.com/questions/90372/difference-between-irq-and-interrupt-priority-level
both are able to affect devices
Do you have any evidence or official documentation for the registry entries affecting anything? At least DevicePriority
is officially documented. As far as i'm concerned, those IRQXPriority
entries are made up until anyone is able to prove otherwise.
Where one is for IRQ (not only devices) and the DevicePriority are for devices only.
Windows Internals mention that it controls IRQ priorities per-device though.
I guess it somewhat make sense to be in this script too
I completely disagree. I wouldn't expect a script that was intended to disable xHCI interrupt moderation to mess with IRQ priorities. The topics are completely unrelated.
if the changes only are microseconds, most would probably not be able to truly do
I'm not talking about benchmarks, I mean whether the setting has any feedback within the OS (e.g. WinDbg). Benchmarking introduces variables which may lead to invalid conclusions in the scenario where there are differences in scores with A vs. B while the registry entry does not even exist.
No, no evidence. Many tweaks might have minor or no affect.
In these cases, if it's there and does nothing, doesnt really matter. Since it shouldnt affect anything. It's not about the bad dissemination that happens on the internet with big videos about it. I just include tweaks that might have a potential positive effect in certain cases, if in total there is positive results, good, if not, doesnt matter.
Since I have no means to verify. If at some point it's verified by someone, it can just be removed.
I always think in the total positive effect in general. Dont really have the means or time to go beyond that. I have just compiled tweaks and built some scripts to automate some aspects. Nothing else. I am saying this because there might be other tweaks that you could ask the same thing.
Some tweaks have negative effects too. Without understanding or justifying the change, it wouldn't be appropriate to apply it to a system in my opinion. Especially if it is being generalised in a script for all systems while every system is different. It is not that big of a deal with a non-existent registry key but helps to prevent spreading false information around the internet. With this mindset, nobody will keep track of what is making a system perform worse or better.
For sure. I told my justification on it above, I can just remove it, though the script are still lacking in the parts that matters, the one to identify the amount of interrupters or the right address.
Here is an answer that goes to your point. https://superuser.com/a/1393759
Main point that needs solution and one of these 2 can be the solution.
1- Identify all interrupters per device, then imod can be disabled (executed at least) in all of them, but not amiss. 2- Identify the correct address, so imod are disabled only in that one, per device.
As for bad tweaks, I asked in the tweaks repo README, for anyone that are interested, to open an issue or create a PR to correct anything, that means remove too.
I removed the IRQ tweak from the script, however I will use it in the other affinity script for the controller of the mouse and keyboard, maybe even GPU.
I also added comments above the script to better give directions to anyone that might want and are able to help, with the remaining issues to be able to finish the script.
The Intel docs demonstrate how the amount of interrupters can be determined. You can also refer to BoringBoredom's updated page. The bits 18:8 align with !usb3kd.xhci_capability
in WinDbg.
Oh, didnt see that he had updated the guide again.
Well, the info was in the Intel docs to begin with. It also seems consistent with other vendors.
Cool, thanks for confirming and helping out. @BoringBoredom @amitxv
I never had any exp reading these types of docs. So, not very used to it. But building this and your explanations helped me understand more. Thanks.
It's done.
Feel free to do a code review if you want.
Pretty much the only thing left is to verify in different OSs. If it's grabbing the interrupters addresses correctly. To know if the implementation are correct / accurate.
For Win7 and Win10 there are different values to differentiate between what is a correct IMOD address, I need to know that the script are currently grabbing the correct address given your OS. I dont know the value in Win11, if it's the same as Win10 or not.
Win7 - 4000 (0x0FA0)
Win10 - 200 (0x00C8)
So, for now, only matters for Win7 and Win10, unless you know how to verify and confirm and are able to do in Win11, let us know.
Though, if it's correct in both win7 and win10, I will consider to be accurate in Win11 too.
Reference: https://www.overclock.net/threads/usb-polling-precision.1550666/page-61#post-28580928
I get both 0x0FA0
and 0x00C8
as value addresses in the script. I am on Win11 22h2 with the new high pooling rate fixes. Not sure if the changes reached imod though.
https://forums.blurbusters.com/viewtopic.php?f=10&t=12157
But they always have zeroes in the imod counter. A review will be necessary it seems.
Pretty much the only thing left is to verify in different OSs. If it's grabbing the interrupters addresses correctly. To know if the implementation are correct / accurate.
The address will always be correct assuming you have the correct offsets and that they are consistent across vendors.
I am on Win11 22h2 with the new high pooling rate fixes. Not sure if the changes reached imod though.
The updated input stack is unrelated to xHCI interrupt moderation. It limits the raw input listening rate for background processes.
https://www.overclock.net/threads/usb-polling-precision.1550666/page-61#post-28582024 EHCI / Interrupt Threshold Control
Is this worth doing? @amitxv @BoringBoredom
What does he mean by offset 0x14? Double click the memory address space used by the controller at offset 0x10, if it's above 4GB you'll need to also use the upper 32-bits. In this example the upper 32-bits (offset 0x14) are zero so no need.
In the following screenshot, he added 0x20
to the BAR1 address. Though in the intel docs, it's MEM_BASE + 20-23h, does it mean from 0x20 to 0x23? BAR1 + 0x20
, BAR1 + 0x21
... and so forth?
I just added support, but not entirely sure if will be accurate, given the remaining questions above. But anyone are free to review and test. I dont have any EHCI device to check.
If no feedback or answer comes, I am considering the script to be complete.
Hello :) I see that the automated script gist is deleted, does anybody still have it? 🙏 Huge thanks in advance
Hey Guys
How did you find the path to rweverything?
Also does anyone all ready have a batch file that disables IMOD if you can send it to me that would be amazing!!!
Hey DJDallmann,
is it possible to autorun a batfile like mentioned in this step? i dont have much experience in coding and such i've done your method and it works for me. but on this other optimization guide,
https://github.com/BoringBoredom/PC-Optimization-Hub/blob/main/content/xhci%20imod/xhci%20imod.md
he mentions a different technique.
is this different? because when trying his method i don't seem to be able to see the "changes" when moving the mouse around. he doesn't have a way directly to contact him so I was wondering if you can help me here.