dynclock.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright 2012 Luke Dashjr
  3. * Copyright 2012 nelisky.btc@gmail.com
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the Free
  7. * Software Foundation; either version 3 of the License, or (at your option)
  8. * any later version. See COPYING for more details.
  9. */
  10. #include "dynclock.h"
  11. #include "miner.h"
  12. void dclk_prepare(struct dclk_data *data)
  13. {
  14. memset(data, 0, sizeof(*data));
  15. }
  16. bool dclk_updateFreq(struct dclk_data *data, dclk_change_clock_func_t changeclock, struct thr_info *thr)
  17. {
  18. struct cgpu_info *cgpu = thr->cgpu;
  19. int i, maxM, bestM;
  20. double bestR, r;
  21. bool rv = true;
  22. for (i = 0; i < data->freqMaxM; i++)
  23. if (data->maxErrorRate[i + 1] * i < data->maxErrorRate[i] * (i + 20))
  24. data->maxErrorRate[i + 1] = data->maxErrorRate[i] * (1.0 + 20.0 / i);
  25. maxM = 0;
  26. while (maxM < data->freqMDefault && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE)
  27. maxM++;
  28. while (maxM < data->freqMaxM && data->errorWeight[maxM] > 150 && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE)
  29. maxM++;
  30. bestM = 0;
  31. bestR = 0;
  32. for (i = 0; i <= maxM; i++) {
  33. r = (i + 1 + (i == data->freqM? DCLK_ERRORHYSTERESIS: 0)) * (1 - data->maxErrorRate[i]);
  34. if (r > bestR) {
  35. bestM = i;
  36. bestR = r;
  37. }
  38. }
  39. if (bestM != data->freqM) {
  40. rv = changeclock(thr, bestM);
  41. }
  42. maxM = data->freqMDefault;
  43. while (maxM < data->freqMaxM && data->errorWeight[maxM + 1] > 100)
  44. maxM++;
  45. if ((bestM < (1.0 - DCLK_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
  46. applog(LOG_ERR, "%s %u: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.",
  47. cgpu->api->name, cgpu->device_id,
  48. (1.0 - 1.0 * bestM / maxM) * 100);
  49. return false;
  50. }
  51. return rv;
  52. }
  53. void dclk_gotNonces(struct dclk_data *data)
  54. {
  55. data->errorCount[data->freqM] *= 0.995;
  56. data->errorWeight[data->freqM] = data->errorWeight[data->freqM] * 0.995 + 1.0;
  57. }
  58. void dclk_errorCount(struct dclk_data *data, double portion)
  59. {
  60. data->errorCount[data->freqM] += portion;
  61. }
  62. void dclk_preUpdate(struct dclk_data *data)
  63. {
  64. 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);
  65. if (data->errorRate[data->freqM] > data->maxErrorRate[data->freqM])
  66. data->maxErrorRate[data->freqM] = data->errorRate[data->freqM];
  67. }