| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /*
- * Copyright 2012 Luke Dashjr
- * Copyright 2012 nelisky.btc@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version. See COPYING for more details.
- */
- #include "dynclock.h"
- #include "miner.h"
- void dclk_prepare(struct dclk_data *data)
- {
- *data = (struct dclk_data){
- .minGoodSamples = 150.,
- };
- }
- void dclk_msg_freqchange(const char *repr, int oldFreq, int newFreq, const char *tail)
- {
- applog(LOG_NOTICE, "%s: Frequency %s from %u to %u Mhz%s",
- repr,
- (oldFreq > newFreq ? "dropped" : "raised "),
- oldFreq, newFreq,
- tail ?: ""
- );
- }
- bool dclk_updateFreq(struct dclk_data *data, dclk_change_clock_func_t changeclock, struct thr_info *thr)
- {
- struct cgpu_info *cgpu = thr->cgpu;
- uint8_t freqMDefault = data->freqMDefault;
- int i, maxM, bestM;
- double bestR, r;
- bool rv = true;
- if (freqMDefault > data->freqMaxM)
- // This occurs when the device in question adjusts its MaxM down due to temperature or similar reasons
- freqMDefault = data->freqMaxM;
- for (i = 0; i < data->freqMaxM; i++)
- if (data->maxErrorRate[i + 1] * i < data->maxErrorRate[i] * (i + 20))
- data->maxErrorRate[i + 1] = data->maxErrorRate[i] * (1.0 + 20.0 / i);
- maxM = 0;
- while (maxM < freqMDefault && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE)
- maxM++;
- while (maxM < data->freqMaxM && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE && data->errorWeight[maxM] >= data->minGoodSamples)
- maxM++;
- bestM = 0;
- bestR = 0;
- for (i = 0; i <= maxM; i++) {
- r = (i + 1 + (i == data->freqM? DCLK_ERRORHYSTERESIS: 0)) * (1 - data->maxErrorRate[i]);
- if (r > bestR) {
- bestM = i;
- bestR = r;
- }
- }
- if (bestM != data->freqM) {
- rv = changeclock(thr, bestM);
- }
- maxM = freqMDefault;
- while (maxM < data->freqMaxM && data->errorWeight[maxM + 1] > 100)
- maxM++;
- if ((bestM < (1.0 - DCLK_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
- applog(LOG_ERR, "%s %u: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.",
- cgpu->api->name, cgpu->device_id,
- (1.0 - 1.0 * bestM / maxM) * 100);
- return false;
- }
- return rv;
- }
- void dclk_gotNonces(struct dclk_data *data)
- {
- data->errorCount[data->freqM] *= 0.995;
- data->errorWeight[data->freqM] = data->errorWeight[data->freqM] * 0.995 + 1.0;
- }
- void dclk_errorCount(struct dclk_data *data, double portion)
- {
- data->errorCount[data->freqM] += portion;
- }
- void dclk_preUpdate(struct dclk_data *data)
- {
- data->errorRate[data->freqM] = data->errorCount[data->freqM] / data->errorWeight[data->freqM] * (data->errorWeight[data->freqM] < 100 ? data->errorWeight[data->freqM] * 0.01 : 1.0);
- if (data->errorRate[data->freqM] > data->maxErrorRate[data->freqM])
- data->maxErrorRate[data->freqM] = data->errorRate[data->freqM];
- }
|