dynclock.c 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright 2012 Luke Dashjr
  3. * Copyright 2012 nelisky
  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 "config.h"
  11. #include "dynclock.h"
  12. #include "miner.h"
  13. void dclk_prepare(struct dclk_data *data)
  14. {
  15. *data = (struct dclk_data){
  16. .minGoodSamples = 150.,
  17. };
  18. }
  19. void dclk_msg_freqchange(const char *repr, int oldFreq, int newFreq, const char *tail)
  20. {
  21. applog(LOG_NOTICE, "%s: Frequency %s from %u to %u MHz%s",
  22. repr,
  23. (oldFreq > newFreq ? "dropped" : "raised "),
  24. oldFreq, newFreq,
  25. tail ?: ""
  26. );
  27. }
  28. bool dclk_updateFreq(struct dclk_data *data, dclk_change_clock_func_t changeclock, struct thr_info *thr)
  29. {
  30. struct cgpu_info *cgpu = thr->cgpu;
  31. uint8_t freqMDefault = data->freqMDefault;
  32. int i, maxM, bestM;
  33. double bestR, r;
  34. bool rv = true;
  35. if (freqMDefault > data->freqMaxM)
  36. // This occurs when the device in question adjusts its MaxM down due to temperature or similar reasons
  37. freqMDefault = data->freqMaxM;
  38. for (i = 0; i < data->freqMaxM; i++)
  39. if (data->maxErrorRate[i + 1] * i < data->maxErrorRate[i] * (i + 20))
  40. data->maxErrorRate[i + 1] = data->maxErrorRate[i] * (1.0 + 20.0 / i);
  41. maxM = 0;
  42. while (maxM < freqMDefault && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE)
  43. maxM++;
  44. while (maxM < data->freqMaxM && data->maxErrorRate[maxM + 1] < DCLK_MAXMAXERRORRATE && data->errorWeight[maxM] >= data->minGoodSamples)
  45. maxM++;
  46. bestM = 0;
  47. bestR = 0;
  48. for (i = 0; i <= maxM; i++) {
  49. r = (i + 1 + (i == data->freqM? DCLK_ERRORHYSTERESIS: 0)) * (1 - data->maxErrorRate[i]);
  50. if (r > bestR) {
  51. bestM = i;
  52. bestR = r;
  53. }
  54. }
  55. if (bestM != data->freqM) {
  56. rv = changeclock(thr, bestM);
  57. }
  58. maxM = freqMDefault;
  59. while (maxM < data->freqMaxM && data->errorWeight[maxM + 1] > 100)
  60. maxM++;
  61. if ((bestM < (1.0 - DCLK_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
  62. applog(LOG_ERR, "%s %u: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.",
  63. cgpu->api->name, cgpu->device_id,
  64. (1.0 - 1.0 * bestM / maxM) * 100);
  65. return false;
  66. }
  67. return rv;
  68. }
  69. void dclk_gotNonces(struct dclk_data *data)
  70. {
  71. data->errorCount[data->freqM] *= 0.995;
  72. data->errorWeight[data->freqM] = data->errorWeight[data->freqM] * 0.995 + 1.0;
  73. }
  74. void dclk_errorCount(struct dclk_data *data, double portion)
  75. {
  76. data->errorCount[data->freqM] += portion;
  77. }
  78. void dclk_preUpdate(struct dclk_data *data)
  79. {
  80. 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);
  81. if (data->errorRate[data->freqM] > data->maxErrorRate[data->freqM])
  82. data->maxErrorRate[data->freqM] = data->errorRate[data->freqM];
  83. }