Minimise the die clock differences in hfa to no more than 50Mhz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
diff --git a/driver-hashfast.c b/driver-hashfast.c
index a53c1bb..2bcb12c 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -1039,6 +1039,7 @@ static void hfa_set_fanspeed(struct cgpu_info *hashfast, struct hashfast_info *i
static void hfa_increase_clock(struct cgpu_info *hashfast, struct hashfast_info *info,
int die)
{
+ int i, high_clock = 0, low_clock = info->hash_clock_rate;
struct hf_die_data *hdd = &info->die_data[die];
uint32_t diebit = 0x00000001ul << die;
uint16_t hdata, increase = 10;
@@ -1046,9 +1047,30 @@ static void hfa_increase_clock(struct cgpu_info *hashfast, struct hashfast_info
if (hdd->hash_clock + increase > info->hash_clock_rate)
increase = info->hash_clock_rate - hdd->hash_clock;
hdd->hash_clock += increase;
+ hdata = (WR_MHZ_INCREASE << 12) | increase;
+ if (info->clock_offset) {
+ for (i = 0; i < info->asic_count; i++) {
+ if (info->die_data[i].hash_clock > high_clock)
+ high_clock = info->die_data[i].hash_clock;
+ if (info->die_data[i].hash_clock < low_clock)
+ low_clock = info->die_data[i].hash_clock;
+ }
+ if (low_clock + HFA_CLOCK_MAXDIFF > high_clock) {
+ /* We can increase all clocks again */
+ for (i = 0; i < info->asic_count; i++) {
+ if (i == die) /* We've already added to this die */
+ continue;
+ info->die_data[i].hash_clock += increase;
+ }
+ applog(LOG_INFO, "%s %d: Die temp below range %.1f, increasing ALL dies by %d",
+ hashfast->drv->name, hashfast->device_id, info->die_data[die].temp, increase);
+ hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), hdata, (uint8_t *)NULL, 0);
+ info->clock_offset -= increase;
+ return;
+ }
+ }
applog(LOG_INFO, "%s %d: Die temp below range %.1f, increasing die %d clock to %d",
hashfast->drv->name, hashfast->device_id, info->die_data[die].temp, die, hdd->hash_clock);
- hdata = (WR_MHZ_INCREASE << 12) | increase;
hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), hdata, (uint8_t *)&diebit, 4);
}
@@ -1058,13 +1080,32 @@ static void hfa_decrease_clock(struct cgpu_info *hashfast, struct hashfast_info
struct hf_die_data *hdd = &info->die_data[die];
uint32_t diebit = 0x00000001ul << die;
uint16_t hdata, decrease = 10;
+ int i, high_clock = 0;
+ /* Find the fastest die for comparison */
+ for (i = 0; i < info->asic_count; i++) {
+ if (info->die_data[i].hash_clock > high_clock)
+ high_clock = info->die_data[i].hash_clock;
+ }
if (hdd->hash_clock - decrease < HFA_CLOCK_MIN)
decrease = hdd->hash_clock - HFA_CLOCK_MIN;
+ hdata = (WR_MHZ_DECREASE << 12) | decrease;
+ if (high_clock >= hdd->hash_clock + HFA_CLOCK_MAXDIFF) {
+ /* We can't have huge differences in clocks as it will lead to
+ * starvation of the faster cores so we have no choice but to
+ * slow down all dies to tame this one. */
+ for (i = 0; i < info->asic_count; i++)
+ info->die_data[i].hash_clock -= decrease;
+ applog(LOG_INFO, "%s %d: Die temp above range %.1f, decreasing ALL die clocks by %d",
+ hashfast->drv->name, hashfast->device_id, info->die_data[die].temp, decrease);
+ hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), hdata, (uint8_t *)NULL, 0);
+ info->clock_offset += decrease;
+ return;
+
+ }
hdd->hash_clock -= decrease;
applog(LOG_INFO, "%s %d: Die temp above range %.1f, decreasing die %d clock to %d",
hashfast->drv->name, hashfast->device_id, info->die_data[die].temp, die, hdd->hash_clock);
- hdata = (WR_MHZ_DECREASE << 12) | decrease;
hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), hdata, (uint8_t *)&diebit, 4);
}
@@ -1072,28 +1113,30 @@ static void hfa_decrease_clock(struct cgpu_info *hashfast, struct hashfast_info
* setting and issuing a work restart with the new clock speed. */
static void hfa_temp_clock(struct cgpu_info *hashfast, struct hashfast_info *info)
{
+ int temp_change, i, low_clock;
time_t now_t = time(NULL);
bool throttled = false;
- int temp_change, i;
if (!opt_hfa_target)
return;
+ /* Only attempt to adjust fanspeed and/or clock speeds if we have
+ * sampled enough temperature data. */
+ if (info->temp_updates < 5)
+ return;
+
/* First find out if any dies are throttled before trying to optimise
- * fanspeed */
+ * fanspeed, and find the slowest clock. */
+ low_clock = info->hash_clock_rate;
for (i = 0; i < info->asic_count ; i++) {
struct hf_die_data *hdd = &info->die_data[i];
- if (hdd->hash_clock < info->hash_clock_rate) {
+ if (hdd->hash_clock < info->hash_clock_rate)
throttled = true;
- break;
- }
+ if (hdd->hash_clock < low_clock)
+ low_clock = hdd->hash_clock;
}
- /* Only attempt to adjust fanspeed and/or clock speeds if we have
- * sampled enough temperature data. */
- if (info->temp_updates < 5)
- return;
/* Find the direction of temperature change since we last checked */
info->temp_updates = 0;
temp_change = info->max_temp - info->last_max_temp;
@@ -1163,6 +1206,11 @@ static void hfa_temp_clock(struct cgpu_info *hashfast, struct hashfast_info *inf
/* Already at max speed */
if (hdd->hash_clock == info->hash_clock_rate)
continue;
+ /* Do not increase the clocks on any dies if we have
+ * a forced offset due to wild differences in clocks,
+ * unless this is the slowest one. */
+ if (info->clock_offset && hdd->hash_clock > low_clock)
+ continue;
hfa_increase_clock(hashfast, info, die);
}
/* Keep track of the last die adjusted since we only adjust
diff --git a/driver-hashfast.h b/driver-hashfast.h
index 4489ce4..f274503 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -31,6 +31,7 @@ char *set_hfa_fan(char *arg);
#define HASHFAST_MINER_THREADS 1
#define HFA_CLOCK_DEFAULT 550
#define HFA_CLOCK_MIN 125
+#define HFA_CLOCK_MAXDIFF 50
#define HFA_TEMP_OVERHEAT 95
#define HFA_TEMP_TARGET 88
#define HFA_TEMP_HYSTERESIS 3
@@ -128,6 +129,7 @@ struct hashfast_info {
int temp_updates;
int fanspeed; // Fanspeed in percent
int last_die_adjusted;
+ int clock_offset;
pthread_t read_thr;
time_t last_restart;