-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fixed incorrect hashrate on mac os and fixed some memleaks #47
base: master
Are you sure you want to change the base?
Changes from 13 commits
2d4c4a2
390939d
37e1870
669c841
79503ad
213d872
6e4d82e
54fd7db
2b786a9
0f8cff8
baeac59
1f952a7
85e58f6
4665206
7a10556
c5ac9c1
fbf742a
b5448e4
8d8af8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
// OpenCL headers are different for Apple. | ||
#ifdef __APPLE__ | ||
#include <OpenCL/opencl.h> | ||
#include <sys/time.h> | ||
#else | ||
#include <CL/cl.h> | ||
#endif | ||
|
@@ -70,19 +71,22 @@ void quitSignal(int unused) { | |
printf("\nCaught kill signal, quitting...\n"); | ||
} | ||
|
||
inline uint64_t get_timestamp_in_us() | ||
{ | ||
#if defined(__linux__) || defined(__APPLE__) | ||
struct timeval now; | ||
gettimeofday(&now, NULL); | ||
return now.tv_sec * 1000000LL + now.tv_usec; | ||
#else | ||
return clock()/ CLOCKS_PER_SEC * 1000000LL; | ||
#endif | ||
} | ||
|
||
// Given a number of cycles per iter, grind nonces will poll Sia for a block | ||
// then do 2^intensity hashes cycles_per_iter times, checking for a successful | ||
// hash each time | ||
// Returns -1 if it finds a block, otherwise it returns the hash_rate of the GPU | ||
double grindNonces(int cycles_per_iter) { | ||
// Start timing this iteration. | ||
#ifdef __linux__ | ||
struct timespec begin, end; | ||
clock_gettime(CLOCK_REALTIME, &begin); | ||
#else | ||
clock_t startTime = clock(); | ||
#endif | ||
|
||
uint8_t blockHeader[80]; | ||
uint8_t target[32] = {255}; | ||
uint8_t nonceOut[8] = {0}; | ||
|
@@ -112,6 +116,9 @@ double grindNonces(int cycles_per_iter) { | |
blockHeader[i + 32] = target[7-i]; | ||
} | ||
|
||
// Start timing this iteration. | ||
int64_t beginInUs = get_timestamp_in_us(); | ||
|
||
// By doing a bunch of low intensity calls, we prevent freezing | ||
// By splitting them up inside this function, we also avoid calling | ||
// get_block_for_work too often. | ||
|
@@ -141,7 +148,7 @@ double grindNonces(int cycles_per_iter) { | |
if (ret != CL_SUCCESS) { | ||
printf("failed to read nonce from buffer: %d\n", ret); exit(1); | ||
} | ||
if (nonceOut[0] != 0) { | ||
if (*(uint64_t *)&nonceOut != 0) { | ||
// Copy nonce to header. | ||
memcpy(blockHeader+32, nonceOut, 8); | ||
if (!submit_header(blockHeader)) { | ||
|
@@ -153,17 +160,12 @@ double grindNonces(int cycles_per_iter) { | |
} | ||
|
||
// Get the time elapsed this function. | ||
#ifdef __linux__ | ||
clock_gettime(CLOCK_REALTIME, &end); | ||
double nsElapsed = 1e9 * (double)(end.tv_sec - begin.tv_sec) + (double)(end.tv_nsec - begin.tv_nsec); | ||
double run_time_seconds = nsElapsed * 1e-9; | ||
#else | ||
double run_time_seconds = (double)(clock() - startTime) / CLOCKS_PER_SEC; | ||
#endif | ||
|
||
// Calculate the hash rate of thie iteration. | ||
double hash_rate = cycles_per_iter * global_item_size / (run_time_seconds*1000000); | ||
return hash_rate; | ||
int64_t endInUs = get_timestamp_in_us(); | ||
int64_t run_time_us = endInUs - beginInUs; | ||
|
||
// Calculate the hash rate of thie iteration. | ||
double hash_rate = cycles_per_iter * global_item_size / (double)run_time_us; | ||
return hash_rate; | ||
} | ||
|
||
// selectOCLDevice manages opencl device selection as requested by the command | ||
|
@@ -243,8 +245,17 @@ void selectOCLDevice(cl_platform_id *OCLPlatform, cl_device_id *OCLDevice, cl_ui | |
// Done. Return the platform ID and device ID object desired, free lists, and return. | ||
*OCLPlatform = platformids[platformid]; | ||
*OCLDevice = deviceids[deviceidx]; | ||
|
||
if (platformids) { | ||
free(platformids); | ||
} | ||
|
||
if (deviceids) { | ||
free(deviceids); | ||
} | ||
} | ||
|
||
|
||
// printPlatformsAndDevices prints out a list of opencl platforms and devices | ||
// that were found on the system. | ||
void printPlatformsAndDevices() { | ||
|
@@ -302,10 +313,33 @@ void printPlatformsAndDevices() { | |
ret = clGetDeviceInfo(deviceids[j], CL_DEVICE_NAME, 80, str, NULL); | ||
if (ret != CL_SUCCESS) { | ||
printf("\tError while getting device info.\n"); | ||
free(deviceids); | ||
continue; | ||
} | ||
printf("\tDevice %d: %s\n", j, str); | ||
} else { | ||
printf("\tDevice %d: %s\n", j, str); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we can't read the device name, does it make sense to continue printing the endianness, alloc size, etc.? I figure if one fails, the rest will probably fail too. I'm not very familiar of OpenCL, though; maybe not all devices have names. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, if we can assume that all devices have names, then the rest of the info should be printed with a double tab instead of repeating the device id. For example:
instead of:
I suppose having a uniform prefix is handy if you want to pipe the output to |
||
|
||
cl_bool isLitlle = CL_TRUE; | ||
ret = clGetDeviceInfo(deviceids[j], CL_DEVICE_ENDIAN_LITTLE, sizeof(isLitlle), &isLitlle, NULL); | ||
if (ret != CL_SUCCESS) { | ||
printf("\tError while getting device CL_DEVICE_ENDIAN_LITTLE.\n"); | ||
} else { | ||
printf("\tDevice %d: isLitlle: %d\n", j, isLitlle); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be more descriptive here. How about: else if (isLittle) {
printf("\t\tEndianness: Little-endian\n");
} else {
printf("\t\tEndianness: Big-endian\n");
} also, please ensure that your new code is properly indented. |
||
|
||
size_t bits = 0; | ||
ret = clGetDeviceInfo(deviceids[j], CL_DEVICE_ADDRESS_BITS, sizeof(bits), &bits, NULL); | ||
if (ret != CL_SUCCESS) { | ||
printf("\tError while getting device CL_DEVICE_ADDRESS_BITS.\n"); | ||
} else { | ||
printf("\tDevice %d: bits: %zu\n", j, bits); | ||
} | ||
|
||
size_t maxMemSize = 0; | ||
ret = clGetDeviceInfo(deviceids[j], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(maxMemSize), &maxMemSize, NULL); | ||
if (ret != CL_SUCCESS) { | ||
printf("\tError while getting device CL_DEVICE_MAX_MEM_ALLOC_SIZE.\n"); | ||
} else { | ||
printf("\tDevice %d: maxMemSize: %zu\n", j, maxMemSize); | ||
} | ||
} | ||
free(deviceids); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like there are a lot of ways to get the current timestamp. This post describes the differences between various functions. I also found this gist by jbenet which shows how to get the current time on OS X. Not sure what the situation is like for Windows.