I'm trying to undervolt different models of AMD RX GPUs on Ubuntu.
I did a lot of research and, as far I know, my two only options are:
- Using ohgodatool to change vddc index
For example ohgodatool -i 0 --core-state 7 --core-vddc-idx 6
, but I don't really understand this.
I'm testing on a RX 470 Mining Edition and on state 6 I have -26. -26 what? 26mV less than the base value? -26%? And what's the base value?
Also, if I understand correctly, I can't choose an arbitrary number of mV.
- Editing the VBIOS
This gives me more control but it's a nightmare.
A few questions: When editing the VoltageObjectInfo portion of the bios, how do I choose the value in mV?
I watched a video that explains this, and they say that the hex value should increase by one for every 6.25mV increase, but again, what's the base value? 0?
A couple more questions:
How does ethOS do this? How can it apply an arbitrary number of mV?
Is there a way to know the current value in mV that the card is using? I didn't find any tools to do this.
Do I have any other option?
Any help is appreciated, thanks.
0 ·
Comments
You can get your card's current value in mVs by:
cat /sys/class/drm/card0/device/pp_voltage
If you using ethos, there's a command: stats
I like the option of editing the kernel module, I'm gonna try to make that work with a value from a config file.
In the meantime I hope someone can help me with the VBIOS thing, I still like that option more.
Thanks for your help!
i'm using wolf's ohgodatool with amdgpu driver from 4.15 kernel on ubuntu (kernel from the ubuntu mainline repository) this way:
>>>
core_clock=1100
mem_clocks=(2000 2000 2000 2000 2000 2000 2000 2000)
# set core/mem states from DPM state 4 upwards to $core_clock and values from mem_clocks()
for gpuid in ${!mem_clocks[*]}; do
echo "Setting up CoreStates and MemClocks GPU$gpuid"
for corestate in {4..7}; do
/usr/sbin/wolfamdctrl -i $gpuid --core-state $corestate --core-clock $core_clock --mem-state 2 --mem-clock ${mem_clocks[$gpuid]}
done
echo manual > /sys/class/drm/card$gpuid/device/power_dpm_force_performance_level
echo 4 > /sys/class/drm/card$gpuid/device/pp_dpm_sclk
done
vddc_voltages=(825 825 825 825 825 825 825 825)
# set all voltage states from 1 upwards to xxx mV:
for gpuid in ${!vddc_voltages[*]}; do
echo "Setting up VDDC Voltage GPU$gpuid"
for voltstate in {1..15}; do
/usr/sbin/wolfamdctrl -i $gpuid --volt-state $voltstate --vddc-table-set ${vddc_voltages[$gpuid]}
done
done
vddci_voltages=(850 850 850 850 850 850 850 850)
# set VDDCI voltages to xxx mV:
for gpuid in ${!vddci_voltages[*]}; do
echo "Setting up VDDC Voltage GPU$gpuid"
for memstate in {1..2}; do
/usr/sbin/wolfamdctrl -i $gpuid --mem-state $memstate --vddci ${vddci_voltages[$gpuid]}
done
done
- in SMOS the tool is renamed to wolfamdctrl
- the number of values in arrays mem_clocks, vddc_voltages & vddci_voltages should match the number of the GPUs in your rig.
I tried your method but it's not working for me, some of the voltage states don't have values in mV (link), if I change all of them to the value I want, the card starts mining at a very low hashrate (3 or 4 MH/s), I tried to leave unchanged the values from 1 to 7 but the result is the same.
I already tested the values in mV on ethOS and they work fine, so that's not the problem.
Any idea?
[email protected]:/opt/tools# ./amd_oc_undervolt.sh.1100
Setting up CoreStates and MemClocks GPU0
Memory state 2 clock: 1750 -> 2025.
DPM state 4 core clock: 1106 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 5 core clock: 1168 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 6 core clock: 1209 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 7 core clock: 1244 -> 1100.
Setting up CoreStates and MemClocks GPU1
Memory state 2 clock: 1750 -> 2025.
DPM state 4 core clock: 1106 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 5 core clock: 1168 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 6 core clock: 1209 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 7 core clock: 1284 -> 1100.
Setting up CoreStates and MemClocks GPU2
Memory state 2 clock: 1750 -> 1850.
DPM state 4 core clock: 1106 -> 1100.
Memory state 2 clock: 1850 -> 1850.
DPM state 5 core clock: 1168 -> 1100.
Memory state 2 clock: 1850 -> 1850.
DPM state 6 core clock: 1209 -> 1100.
Memory state 2 clock: 1850 -> 1850.
DPM state 7 core clock: 1244 -> 1100.
Setting up CoreStates and MemClocks GPU3
Memory state 2 clock: 1750 -> 2000.
DPM state 4 core clock: 1106 -> 1100.
Memory state 2 clock: 2000 -> 2000.
DPM state 5 core clock: 1168 -> 1100.
Memory state 2 clock: 2000 -> 2000.
DPM state 6 core clock: 1209 -> 1100.
Memory state 2 clock: 2000 -> 2000.
DPM state 7 core clock: 1244 -> 1100.
Setting up CoreStates and MemClocks GPU4
Memory state 2 clock: 1750 -> 2025.
DPM state 4 core clock: 1106 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 5 core clock: 1168 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 6 core clock: 1209 -> 1100.
Memory state 2 clock: 2025 -> 2025.
DPM state 7 core clock: 1244 -> 1100.
Setting up VDDC Voltage GPU0
Voltage table index 1: 65282 -> 800.
Voltage table index 2: 65283 -> 800.
Voltage table index 3: 65284 -> 800.
Voltage table index 4: 65285 -> 800.
Voltage table index 5: 65286 -> 800.
Voltage table index 6: 65287 -> 800.
Voltage table index 7: 65288 -> 800.
Voltage table index 8: 800 -> 800.
Voltage table index 9: 850 -> 800.
Voltage table index 10: 900 -> 800.
Voltage table index 11: 950 -> 800.
Voltage table index 12: 1000 -> 800.
Voltage table index 13: 1050 -> 800.
Voltage table index 14: 1100 -> 800.
Voltage table index 15: 1150 -> 800.
Setting up VDDC Voltage GPU1
Voltage table index 1: 65282 -> 825.
Voltage table index 2: 65283 -> 825.
Voltage table index 3: 65284 -> 825.
Voltage table index 4: 65285 -> 825.
Voltage table index 5: 65286 -> 825.
Voltage table index 6: 65287 -> 825.
Voltage table index 7: 65288 -> 825.
Voltage table index 8: 800 -> 825.
Voltage table index 9: 850 -> 825.
Voltage table index 10: 900 -> 825.
Voltage table index 11: 950 -> 825.
Voltage table index 12: 1000 -> 825.
Voltage table index 13: 1050 -> 825.
Voltage table index 14: 1100 -> 825.
Voltage table index 15: 1150 -> 825.
Setting up VDDC Voltage GPU2
Voltage table index 1: 65282 -> 825.
Voltage table index 2: 65283 -> 825.
Voltage table index 3: 65284 -> 825.
Voltage table index 4: 65285 -> 825.
Voltage table index 5: 65286 -> 825.
Voltage table index 6: 65287 -> 825.
Voltage table index 7: 65288 -> 825.
Voltage table index 8: 800 -> 825.
Voltage table index 9: 850 -> 825.
Voltage table index 10: 900 -> 825.
Voltage table index 11: 950 -> 825.
Voltage table index 12: 1000 -> 825.
Voltage table index 13: 1050 -> 825.
Voltage table index 14: 1100 -> 825.
Voltage table index 15: 1150 -> 825.
Setting up VDDC Voltage GPU3
Voltage table index 1: 65282 -> 800.
Voltage table index 2: 65283 -> 800.
Voltage table index 3: 65284 -> 800.
Voltage table index 4: 65285 -> 800.
Voltage table index 5: 65286 -> 800.
Voltage table index 6: 65287 -> 800.
Voltage table index 7: 65288 -> 800.
Voltage table index 8: 800 -> 800.
Voltage table index 9: 850 -> 800.
Voltage table index 10: 900 -> 800.
Voltage table index 11: 950 -> 800.
Voltage table index 12: 1000 -> 800.
Voltage table index 13: 1050 -> 800.
Voltage table index 14: 1100 -> 800.
Voltage table index 15: 1150 -> 800.
Setting up VDDC Voltage GPU4
Voltage table index 1: 65282 -> 812.
Voltage table index 2: 65283 -> 812.
Voltage table index 3: 65284 -> 812.
Voltage table index 4: 65285 -> 812.
Voltage table index 5: 65286 -> 812.
Voltage table index 6: 65287 -> 812.
Voltage table index 7: 65288 -> 812.
Voltage table index 8: 800 -> 812.
Voltage table index 9: 850 -> 812.
Voltage table index 10: 900 -> 812.
Voltage table index 11: 950 -> 812.
Voltage table index 12: 1000 -> 812.
Voltage table index 13: 1050 -> 812.
Voltage table index 14: 1100 -> 812.
Voltage table index 15: 1150 -> 812.
Setting up VDDC Voltage GPU0
Memory state 1 VDDCI: 850 -> 800.
Memory state 2 VDDCI: 900 -> 800.
Setting up VDDC Voltage GPU1
Memory state 1 VDDCI: 850 -> 800.
Memory state 2 VDDCI: 900 -> 800.
Setting up VDDC Voltage GPU2
Memory state 1 VDDCI: 850 -> 800.
Memory state 2 VDDCI: 900 -> 800.
Setting up VDDC Voltage GPU3
Memory state 1 VDDCI: 850 -> 800.
Memory state 2 VDDCI: 900 -> 800.
Setting up VDDC Voltage GPU4
Memory state 1 VDDCI: 850 -> 800.
Memory state 2 VDDCI: 900 -> 800.
i did a small modification to the script, added the desired dpm state
[email protected]:/opt/tools$ more amd_oc_undervolt.sh
#!/bin/bash
# RX570 reference DPM states (0:300, 1:588, 2:952, 3:1041, 4:1106, 5:1168, 6:1209, 7:1244)
# for the desired core_clock choose dpm_state close to reference value, e.g. 1100MHz->4, 1150MHz->5
core_clock=1100
dpm_state=4
# mem_clocks=(2000 2000 2000 2000 2000 2000 2000 2000)
mem_clocks=(2000 2000 1975 2000 2000 2000 2000)
# set core/mem states from DPM state 4 upwards to $core_clock
for gpuid in ${!mem_clocks[*]}; do
echo "Setting up CoreStates and MemClocks GPU$gpuid"
for corestate in `seq $dpm_state 7`; do
./wolfamdctrl -i $gpuid --core-state $corestate --core-clock $core_clock --mem-state 2 --mem-clock ${mem_clocks[$gpuid]}
done
echo manual > /sys/class/drm/card$gpuid/device/power_dpm_force_performance_level
echo $dpm_state > /sys/class/drm/card$gpuid/device/pp_dpm_sclk
done
# vddc_voltages; start from 800mV, increase if
vddc_voltages=(800 800 800 800 800 800 800)
# set all voltage states from 1 upwards to xxx mV:
for gpuid in ${!vddc_voltages[*]}; do
echo "Setting up VDDC Voltage GPU$gpuid"
for voltstate in {1..15}; do
./wolfamdctrl -i $gpuid --volt-state $voltstate --vddc-table-set ${vddc_voltages[$gpuid]}
done
done
# vddci_voltages; should work @800mV for all GPU
vddci_voltages=(800 800 800 800 800 800 800)
# set VDDCI voltages to xxx mV:
for gpuid in ${!vddci_voltages[*]}; do
echo "Setting up VDDC Voltage GPU$gpuid"
for memstate in {1..2}; do
./wolfamdctrl -i $gpuid --mem-state $memstate --vddci ${vddci_voltages[$gpuid]}
done
done
I might try to switch to that one if I don't find a different solution.
1) Undervolting .. and ..
2) Setting the power limit ?
I only use option [2] ( by updating the BIOS using Polaris Bios Editor in Linux ) to set max power limit to 110W.
Using rocm-smi -P, it shows my average GPU power is 108.178 W.
I never tried undervolting as, I guess, I was too worried that it would "break" the GPU card if I get it wrong.
Thus, I opted to set the max power limit instead.
With an Sapphire Nitro+ RX 580, after using Polaris Bios Editor in Linux to copy the memory timing from 1500 to all other timings above 1500 ( separately for UEFI and legacy ) to increase hashrate, I get 27.20 Mh/s. ( Stock was around 22 Mh/s ) GPU was drawing about 140+W ( or was it 150+W ? ).
Then, again using Polaris Bios Editor for Linux, I set the power limit to 110W to reduce power while maintaining the hashrate.
So now, I have 27+ Mh/s at 110W.
I have not bothered trying to increase the hashrate further.
[email protected]:~$ /opt/rocm/bin/rocm-smi
==================== ROCm System Management Interface ====================
================================================================================
GPU Temp AvgPwr SCLK MCLK Fan Perf SCLK OD
5 62.0c 76.70W 1100Mhz 2120Mhz 31.76% manual 0%
3 64.0c 78.68W 1100Mhz 2140Mhz 31.76% manual 0%
1 70.0c 78.60W 1100Mhz 2100Mhz 31.76% manual 0%
6 61.0c 76.208W 1100Mhz 2140Mhz 31.76% manual 0%
4 57.0c 78.3W 1100Mhz 2100Mhz 31.76% manual 0%
2 71.0c 77.134W 1100Mhz 2120Mhz 33.73% manual 0%
0 66.0c 78.167W 1100Mhz 2120Mhz 31.76% manual 0%
7 64.0c 77.229W 1100Mhz 2140Mhz 31.76% manual 0%
================================================================================
==================== End of ROCm SMI Log ====================
So I presume I can:
1) Keep my current mod BIOS with the 1500 memory timings and max power limit .. AND ..
2) Use ohgodatool ( woldamdctrl ?? ) to undervolt. ( Never used it as I found it too daunting ... and I thought you have to pay ohgodagirl 1.5 BTC ? )
... to bring down the power usage further to below 90W.
This is not the same as undervolting.
I have to mention that:
1) I am using amdgpu-pro, not amdgpu that comes with stock Ubuntu .. with the large page parameters set on grub as per AMD's instructions.
2) Still using 4.10.0-42 ( Using 4.12/4.13 .. the hashrate decreases a lot due to that Spectre patch ).
3) I copied the 1500 timings to the higher clocks ( separately for UEFI and for legacy )
4) I have set max memory clock to 2000 MHz:
5) Also, to be clear, the field edited in Polaris Bios Editor is called "Max Power Limit (W)" under PowerTune ( this was the last step I did ):
Before I did [5], I ran ethminer for several hours.
After I did [5], my hashrate was the same as before [5] but at lower power.
Now you got me interested.
So I presume I can:
1) Keep my current mod BIOS with the 1500 memory timings and max power limit .. AND ..
2) Use ohgodatool ( woldamdctrl ?? ) to undervolt. ( Never used it as I found it too daunting ... and I thought you have to pay ohgodagirl 1.5 BTC ? )
... to bring down the power usage further to below 90W.
1) - yes, you can keep Your vbios as it is, if there is no VRM offset set in vbios.
2) - the paid version of the tool is called ohgodavolt. afaik, it is accessing the GPU I2C bus (through the /dev/memctl) and it is doing undervolt by changing the VRM voltage offset.
https://forum.ethereum.org/discussion/12970/undervolting-through-hex-editor-simplemining
2) - the paid version of the tool is called ohgodavolt. afaik, it is accessing the GPU I2C bus (through the /dev/memctl) and it is doing undervolt by changing the VRM voltage offset.
https://forum.ethereum.org/discussion/12970/undervolting-through-hex-editor-simplemining
I presume I only need to do the following:
1) From your script:
vddc_voltages=(825 825 825 825 825 825 825 825) # set all voltage states from 1 upwards to xxx mV: for gpuid in ${!vddc_voltages[*]}; do echo "Setting up VDDC Voltage GPU$gpuid" for voltstate in {1..15}; do /usr/sbin/wolfamdctrl -i $gpuid --volt-state $voltstate --vddc-table-set ${vddc_voltages[$gpuid]} done done
2) From your script, the following:
vddci_voltages=(850 850 850 850 850 850 850 850) # set VDDCI voltages to xxx mV: for gpuid in ${!vddci_voltages[*]}; do echo "Setting up VDDC Voltage GPU$gpuid" for memstate in {1..2}; do /usr/sbin/wolfamdctrl -i $gpuid --mem-state $memstate --vddci ${vddci_voltages[$gpuid]} done done
.. I presume can be done via Polaris Bios Editor ... but the Polaris Bios Editor shows:
... from which I can change the mV for each memory clock. However, looking at that screenshot and the output from ohgodatool:
/OhGodATool$ sudo ./ohgodatool -i 2 --show-mem
Memory state 0:
VDDC: 750
VDDCI: 800
VDDC GFX offset: 0
MVDD: 1000
Memory clock: 300
Memory state 1:
VDDC: 65282
VDDCI: 850
VDDC GFX offset: 0
MVDD: 1000
Memory clock: 1000
Memory state 2:
VDDC: 65283
VDDCI: 950
VDDC GFX offset: 0
MVDD: 1000
Memory clock: 2000
... the Polaris Bios Editor seems to allow me to edit MVDD, but your script modifies VDDCI.
What's MVDD vs VDDCI ?
The other part of your script ( below ) I presume I don't need as I have already set the max memory Mhz to 2000 MHz and copied the 1500 timings to higher straps.
core_clock=1100
mem_clocks=(2000 2000 2000 2000 2000 2000 2000 2000)
# set core/mem states from DPM state 4 upwards to $core_clock and values from mem_clocks()
for gpuid in ${!mem_clocks[*]}; do
echo "Setting up CoreStates and MemClocks GPU$gpuid"
for corestate in {4..7}; do
/usr/sbin/wolfamdctrl -i $gpuid --core-state $corestate --core-clock $core_clock --mem-state 2 --mem-clock ${mem_clocks[$gpuid]}
done
echo manual > /sys/class/drm/card$gpuid/device/power_dpm_force_performance_level
echo 4 > /sys/class/drm/card$gpuid/device/pp_dpm_sclk
done
I presume that:
(A) I DO NOT need the following since I have already set the max memory clock to 2000 Mhz and copied the 1500 timing straps to higher clocks:
core_clock=1100 mem_clocks=(2000 2000 2000 2000 2000 2000 2000 2000) # set core/mem states from DPM state 4 upwards to $core_clock and values from mem_clocks() for gpuid in ${!mem_clocks[*]}; do echo "Setting up CoreStates and MemClocks GPU$gpuid" for corestate in {4..7}; do /usr/sbin/wolfamdctrl -i $gpuid --core-state $corestate --core-clock $core_clock --mem-state 2 --mem-clock ${mem_clocks[$gpuid]} done echo manual > /sys/class/drm/card$gpuid/device/power_dpm_force_performance_level echo 4 > /sys/class/drm/card$gpuid/device/pp_dpm_sclk done
(B) I need the following:
vddc_voltages=(825 825 825 825 825 825 825 825) # set all voltage states from 1 upwards to xxx mV: for gpuid in ${!vddc_voltages[*]}; do echo "Setting up VDDC Voltage GPU$gpuid" for voltstate in {1..15}; do /usr/sbin/wolfamdctrl -i $gpuid --volt-state $voltstate --vddc-table-set ${vddc_voltages[$gpuid]} done done
(C) I also need the following:
vddci_voltages=(850 850 850 850 850 850 850 850) # set VDDCI voltages to xxx mV: for gpuid in ${!vddci_voltages[*]}; do echo "Setting up VDDC Voltage GPU$gpuid" for memstate in {1..2}; do /usr/sbin/wolfamdctrl -i $gpuid --mem-state $memstate --vddci ${vddci_voltages[$gpuid]} done done
In Polaris Bios Editor, I can ( but have not ) modify the mV for each memory clock:
which when compared to ohgodatool, is the MVDD:
~/OhGodATool$ sudo ./ohgodatool -i 2 --show-mem Memory state 0: VDDC: 750 VDDCI: 800 VDDC GFX offset: 0 MVDD: 1000 Memory clock: 300 Memory state 1: VDDC: 65282 VDDCI: 850 VDDC GFX offset: 0 MVDD: 1000 Memory clock: 1000 Memory state 2: VDDC: 65283 VDDCI: 950 VDDC GFX offset: 0 MVDD: 1000 Memory clock: 2000
What's the difference between changing MVDD via Polaris Bios Editor versus your script in [C] which changes VDDCI ?
What's MVDD and VDDCI acronyms anyway ?
http://www.geeks3d.com/20101107/radeon-hd-6870-voltage-check-points-vddc-vddci-and-mvdd/
afaik, from power saving perspective, changing the MVDD does not make sense. PBE allows You to change MVDD.
i'm not changing memory clocks in vbios anymore, since the tool does it for me.
My prior post disappeared for whatever reason. .. tried it again and that one disappeared too.
Sorry if you got my previous post twice.
I am just using the following ( and only the following ):
ohgodatool -i 2 --mem-state 2 --vddci 850
.. and as soon as I do the above, the GPU fan slows down and my hashrate drops from 27Mh/s to 24Mh/s.
If I bring it back up to its original value of 950mv:
ohgodatool -i 2 --mem-state 2 --vddci 950
.. the hashrate never goes back up to 27Mh/s
I rebooted to bring everything back to my normal hashrate and original values. I thought maybe I need to set the performance level to manual BEFORE setting the VDDCI on the
echo manual > /sys/class/drm/card2/device/power_dpm_force_performance_level
echo 5 > /sys/class/drm/card2/device/pp_dpm_sclk
echo 2 > /sys/class/drm/card2/device/pp_dpm_mclk
ohgodatool -i 2 --mem-state 2 --vddci 850
.. same thing happened ... GPU fan slows down and hashrate drops from 27Mh/s to 24Mh/s. If I restore vddci back to 950 and set performance_level back to auto, hashrate does not go back up to 27 Mh/s.
Any suggestions ?
i assume we are talking about mining ethash algo. what miner you are using
Attached is a tar.gz of the original and the modified bios I am using.
( Sapphire Nitro+ RX 580 Elpida )
The only modifications I made are:
1) Mem timings from 1500 to higher clocks for both UEFI and legacy
2) Max mem to 2000 MHz
3) Max power to 110W
for the RX580, the figures will be higher but not significantly
looking at your modified vbios, i would suggest to change:
1.) max power limit
- your max power limit is only 5W higher then the TDP.
- i'm setting the max power limit to +20/+30 watts above the TDP similarly as it is in stock vbios.
- i would suggest to set the TDP between 100-110W and max power limit between 130-140W
2.) mem strap for Elpida
- i'm using the following memstrap for Elpida EDW4032
777000000000000022AA1C00AC615B3CA0550F142C8C1506006004007C041420CA8980A9020004C01712262B612B3715
- make sure, you change the correct memstrap in PBE. the nitro has a combined vbios with a timing for elpida and hynix