Pages:
Author

Topic: Phoenix - Efficient, fast, modular miner - page 41. (Read 760839 times)

legendary
Activity: 1540
Merit: 1002
I'm torn. On one hand I want to fix this... But on the other hand, since the possibility of a block both passing both the
H=0 requirement to get returned to the host and the nonce=0 requirement to get discarded by the caveat is highly improbable,

Heh I know. But I'm perfectionist here, and modified OpenCL code has only 1/2^32 chance of actually being slower in execution, because it's all enclosed inside an "if" conditional. So it isn't making calculations any slower, actually.


Beware, though, that 'if' statements make paralel optimization harder and the opencl runtime may end up being a LOT slower with a simple conditional branch command that looks all innocent.
sr. member
Activity: 298
Merit: 250
I'm torn. On one hand I want to fix this... But on the other hand, since the possibility of a block both passing both the
H=0 requirement to get returned to the host and the nonce=0 requirement to get discarded by the caveat is highly improbable,

Heh I know. But I'm perfectionist here, and modified OpenCL code has only 1/2^32 chance of actually being slower in execution, because it's all enclosed inside an "if" conditional. So it isn't making calculations any slower, actually.
member
Activity: 63
Merit: 10
Wouldn't it be best to just not worry?  That equates to a loss of 1/2^32 of hashing power, or a loss of 0.00000002%.  The CPU cycles expended in making sure that zero nonce was always covered would cause a greater net loss.

1/2^64, since the hash must first be low enough (1/2^32) for the GPU to try to send it back to the CPU before the nonce=0 caveat is even a factor.
It's a good exercise to identify and work out a solution to the problem, but in practice it's really not worthwhile to worry about. Smiley
vip
Activity: 1386
Merit: 1140
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
I think that I have found a bug in your miner.

If the solving nonce is ZERO it is silently ignored. But you already have a framework introduced specifically to avoid this problem!

This happens because you check if last item in self.output[self.OUTPUT_SIZE] is not zero:

That particular caveat did bother me a little while I was writing the postprocess function...
I think the easiest fix might be to unconditionally check the 0-nonce in the CPU before doing any mining in the GPU...

I'm torn. On one hand I want to fix this... But on the other hand, since the possibility of a block both passing both the
H=0 requirement to get returned to the host and the nonce=0 requirement to get discarded by the caveat is highly improbable,
(1 in 2^64) it might be better to choose simplicity over correctness/completeness in this case.


Wouldn't it be best to just not worry?  That equates to a loss of 1/2^32 of hashing power, or a loss of 0.00000002%.  The CPU cycles expended in making sure that zero nonce was always covered would cause a greater net loss.
member
Activity: 63
Merit: 10
I think that I have found a bug in your miner.

If the solving nonce is ZERO it is silently ignored. But you already have a framework introduced specifically to avoid this problem!

This happens because you check if last item in self.output[self.OUTPUT_SIZE] is not zero:

That particular caveat did bother me a little while I was writing the postprocess function...
I think the easiest fix might be to unconditionally check the 0-nonce in the CPU before doing any mining in the GPU...

I'm torn. On one hand I want to fix this... But on the other hand, since the possibility of a block both passing both the
H=0 requirement to get returned to the host and the nonce=0 requirement to get discarded by the caveat is highly improbable,
(1 in 2^64) it might be better to choose simplicity over correctness/completeness in this case.

I just wanted clarification on running a dual GPU setup. From what I understand is you simply need to run a second instance of this problem contained in a separate folder AND you change device=0 to device=1.
Also, do you have to have the second one connected to a monitor or a dummy plug? Or can you someone do that in the code.

You don't even need to put it in a separate folder. Just start start it twice: one instance with DEVICE=0 and the other with DEVICE=1.
You will probably need a dummy plug if you're on Windows. I don't know enough to say, though.
sr. member
Activity: 714
Merit: 250
I just wanted clarification on running a dual GPU setup. From what I understand is you simply need to run a second instance of this problem contained in a separate folder AND you change device=0 to device=1.
Also, do you have to have the second one connected to a monitor or a dummy plug? Or can you someone do that in the code.
sr. member
Activity: 298
Merit: 250
Hmm.. ok, this patch will not solve the problem, because later in postprocess you are again checking against zero:

Code:
        for i in xrange(self.OUTPUT_SIZE):
            if output[i]:

but it's still possible to fix it.

OK, so how about this fix:

Code:
Index: kernels/poclbm/kernel.cl
===================================================================
--- kernels/poclbm/kernel.cl    (revision 56)
+++ kernels/poclbm/kernel.cl    (working copy)
@@ -296,16 +296,32 @@
 #ifdef VECTORS
        if (H.x == 0)
        {
-               output[OUTPUT_SIZE] = output[nonce.x & OUTPUT_MASK] = nonce.x;
+               if(nonce.x == 0) {
+                       output[OUTPUT_SIZE] = 2;
+               } else {
+                       output[OUTPUT_SIZE] = 1;
+                       output[nonce.x & OUTPUT_MASK] = nonce.x;
+               }
        }
-       else if (H.y == 0)
+       if (H.y == 0) // without "else" clause, because it can happen that both nonces are a solution
        {
-               output[OUTPUT_SIZE] = output[nonce.y & OUTPUT_MASK] = nonce.y;
+               if(nonce.y == 0) {
+                       output[OUTPUT_SIZE] = 2;
+               } else {
+                       output[OUTPUT_SIZE] = 1;
+                       output[nonce.y & OUTPUT_MASK] = nonce.y;
+               }
        }
 #else
        if (H == 0)
        {
-               output[OUTPUT_SIZE] = output[nonce & OUTPUT_MASK] = nonce;
+               if(nonce == 0) {
+                       output[OUTPUT_SIZE] = 2;
+               } else {
+                       output[OUTPUT_SIZE] = 1;
+                       output[nonce & OUTPUT_MASK] = nonce;
+               }
        }
 #endif
-}
\ No newline at end of file
+}
+
Index: kernels/poclbm/__init__.py
===================================================================
--- kernels/poclbm/__init__.py  (revision 56)
+++ kernels/poclbm/__init__.py  (working copy)
@@ -346,12 +346,21 @@
         # Iterate over only the first OUTPUT_SIZE items. Exclude the last item
         # which is a duplicate of the most recently-found nonce.
         for i in xrange(self.OUTPUT_SIZE):
            if output[i]:   
                 if not self.interface.foundNonce(nr, int(output[i])):
                     hash = self.interface.calculateHash(nr, int(output[i]))
                     if not hash.endswith('\x00\x00\x00\x00'):
                         self.interface.error('Unusual behavior from OpenCL. '
                             'Hardware problem?')
+        if(self.output[self.OUTPUT_SIZE] == 2):
+            self.interface.log("Nearly impossible happened! Found solving nonce which is ZERO !")
+            if not self.interface.foundNonce(nr, 0):
+                hash = self.interface.calculateHash(nr, 0)
+                if not hash.endswith('\x00\x00\x00\x00'):
+                    self.interface.error('Unusual behavior from OpenCL. '
+                        'Hardware problem?')
     
     def mineThread(self):
         for data in self.qr:
@@ -376,11 +385,14 @@
             # The OpenCL code will flag the last item in the output buffer when
             # it finds a valid nonce. If that's the case, send it to the main
             # thread for postprocessing and clean the buffer for the next pass.
-            if self.output[self.OUTPUT_SIZE]:
+            if(self.output[self.OUTPUT_SIZE] > 0):
                 reactor.callFromThread(self.postprocess, self.output.copy(),
                 data.nr)
             
                 self.output.fill(0)
                 cl.enqueue_write_buffer(
                     self.commandQueue, self.output_buf, self.output)

full member
Activity: 188
Merit: 100
It's nice to be right...

...and I promised that I'll test it soon Smiley.

Yes you did. Grin
hero member
Activity: 531
Merit: 505
Is the hashrate of the Phoenix miner reported accurately?

I found out that using AGGRESSION=11 I can get up to 2x 400 MH/sec on 2x Radeon HD5870 at 965/300 clocks. The GPU usage is above 97% and the cards generate a lot of heat and the GUI is very irresponsible.

Surprisingly, using AGGRESSION=7 FASTLOOP I can get up to 2x430 MH/sec (!!!) while the GUI is slowed just a bit and the GPU usage is about 92% and the cards are a lot cooler. The power consumption lowers, too.

I mine using deepbit.net and its reported hashrate varies a lot, so I cannot count on it.

Does simply higher local reported hashrate mean *always* faster calculation and more per-day yield? Or is the hashrate reported in Phoenix also just approximate and may vary depending on various system settings (clocks, latency, etc.)?


sr. member
Activity: 298
Merit: 250
Hmm.. ok, this patch will not solve the problem, because later in postprocess you are again checking against zero:

Code:
        for i in xrange(self.OUTPUT_SIZE):
            if output[i]:

but it's still possible to fix it.
sr. member
Activity: 298
Merit: 250
I think that I have found a bug in your miner.

If the solving nonce is ZERO it is silently ignored. But you already have a framework introduced specifically to avoid this problem!

This happens because you check if last item in self.output[self.OUTPUT_SIZE] is not zero:
Code:
       if self.output[self.OUTPUT_SIZE]:
                reactor.callFromThread(self.postprocess, self.output.copy(),
                data.nr)

and in openCL kernel you assign nonce to it:

Code:
#ifdef VECTORS
        if (H.x == 0)
        {
                output[OUTPUT_SIZE] = output[nonce.x & OUTPUT_MASK] = nonce.x;
        }
        else if (H.y == 0)
        {
                output[OUTPUT_SIZE] = output[nonce.y & OUTPUT_MASK] = nonce.y;
        }
#else
        if (H == 0)
        {
                output[OUTPUT_SIZE] = output[nonce & OUTPUT_MASK] = nonce;
        }
#endif

I think that following patch will fix the bug:

Code:
Index: kernels/poclbm/kernel.cl
===================================================================
--- kernels/poclbm/kernel.cl    (revision 56)
+++ kernels/poclbm/kernel.cl    (working copy)
@@ -296,16 +296,20 @@
 #ifdef VECTORS
        if (H.x == 0)
        {
-               output[OUTPUT_SIZE] = output[nonce.x & OUTPUT_MASK] = nonce.x;
+               output[OUTPUT_SIZE] = 1;
+               output[nonce.x & OUTPUT_MASK] = nonce.x;
        }
        else if (H.y == 0)
        {
-               output[OUTPUT_SIZE] = output[nonce.y & OUTPUT_MASK] = nonce.y;
+               output[OUTPUT_SIZE] = 1;
+               output[nonce.y & OUTPUT_MASK] = nonce.y;
        }
 #else
        if (H == 0)
        {
-               output[OUTPUT_SIZE] = output[nonce & OUTPUT_MASK] = nonce;
+               output[OUTPUT_SIZE] = 1;
+               output[nonce & OUTPUT_MASK] = nonce;
        }
 #endif
-}
\ No newline at end of file
+}
+

how do you think?
sr. member
Activity: 298
Merit: 250
I like to know what DEVICE each miner is running on. And in cssh I'm using very compact terminals, so they all fit on a screen, so I like more compact status line. Here's a diff for anyone interested:

Code:
Index: phoenix.py
===================================================================
--- phoenix.py  (revision 56)
+++ phoenix.py  (working copy)
@@ -110,6 +110,7 @@
                 exit()
             kernelModule = imp.load_module(module, file, filename, smt)
             self.kernel = kernelModule.MiningKernel(requester)
+           self.logger.DEVICE = self.kernel.DEVICE
         return self.kernel

     def makeQueue(self, requester):
@@ -122,4 +123,4 @@
     miner = Miner()
     miner.start(options)

-    reactor.run()
\ No newline at end of file
+    reactor.run()
Index: ConsoleLogger.py
===================================================================
--- ConsoleLogger.py    (revision 56)
+++ ConsoleLogger.py    (working copy)
@@ -56,6 +56,7 @@
         self.lineLength = 0
         self.connectionType = None
         self.idle = False
+       self.DEVICE = -1

     def reportRate(self, rate, update=True):
         """Used to tell the logger the current Khash/sec."""
@@ -115,9 +116,9 @@
             rate = self.rate if (not self.idle) else 0
             type = " [" + str(self.connectionType) + "]" if self.connectionType is not None else ''
             status = (
-                "[" + formatNumber(rate) + "hash/sec] "
-                "[" + str(self.accepted) + " Accepted] "
-                "[" + str(self.invalid) + " Rejected]" + type)
+                "[" + formatNumber(rate) + "Hs/s] "
+                "[" + str(self.accepted) + " Acc] "
+                "[" + str(self.invalid) + " Rej]" + type + " [D "+str(self.DEVICE)+"]")
             self.say(status)
             self.lastUpdate = time()

@@ -152,4 +153,4 @@
         self.say(message, True, hideTimestamp)
         if update:
             self.updateStatus(True)
-       
\ No newline at end of file


I am learning python, so I am sure that this can be written in a better way. I would like to learn in which way? Anyway, this diff will produce a status line like this:

Code:
[298.44 MHs/s] [15 Acc] [0 Rej] [RPC (+LP)] [D 3]

the last number is the device number.
member
Activity: 90
Merit: 10
How many M/s can be achieved on the Radeon HD5850?

depends on gpuclock/bios and miner-settings,
~295Mhash/s @775MHz
~345Mhash/s @900MHz

i get 270Mhash/s @ 725Mhz (stock clock, memory at 300 or 1000 doesnt really make a difference)

do u change the voltage to get 775 or 900?, or do i just need to put it at 775 or 900 (i doubt it will do 900 without voltage ajustment, but doesnt hurt to ask)
legendary
Activity: 1386
Merit: 1097
It's nice to be right...

...and I promised that I'll test it soon Smiley.
newbie
Activity: 17
Merit: 0
Ok. Thanks for reply.
hero member
Activity: 532
Merit: 505
How many M/s can be achieved on the Radeon HD5850?

depends on gpuclock/bios and miner-settings,
~295Mhash/s @775MHz
~345Mhash/s @900MHz
newbie
Activity: 17
Merit: 0
How many M/s can be achieved on the Radeon HD5850?
full member
Activity: 188
Merit: 100
I tried 3 computes at once with a total of 9 instances of Phoenix. It worked as expected.

I tried it on my two rigs and had this problem, too. It must be specific to the miner, because I used diablo and poclbm without any problem before.

Once I started at least one phoenix miner, other miners on second machine suddenly stopped working. More phoenix miners on the same machine works without problem. I tried to stop pool's firewall (where are some advanced anti-DoS techniques enabled), but no difference. Currently I have absolute no idea where the problem can be and problem indices sounds really weird. My two rigs aren't linked together in any way, they are even mining under separate pool accounts and I have no other limitations on the pool except the firewall. As this problem occured only with phoenix, there must be _something_ different than in other miners... Still no idea?

It's nice to be right. I had the same issue and I narrowed it down to the Phoenix miner. I told slush about this problem yesterday.
legendary
Activity: 1386
Merit: 1097
We might end up needing to give you a modified build that logs additional info when this happens if we can't find the problem.

Good idea, if you add hooks to correct places, I can collect some logs for further investigation...
full member
Activity: 219
Merit: 120
I tried 3 computes at once with a total of 9 instances of Phoenix. It worked as expected.

I tried it on my two rigs and had this problem, too. It must be specific to the miner, because I used diablo and poclbm without any problem before.

Once I started at least one phoenix miner, other miners on second machine suddenly stopped working. More phoenix miners on the same machine works without problem. I tried to stop pool's firewall (where are some advanced anti-DoS techniques enabled), but no difference. Currently I have absolute no idea where the problem can be and problem indices sounds really weird. My two rigs aren't linked together in any way, they are even mining under separate pool accounts and I have no other limitations on the pool except the firewall. As this problem occured only with phoenix, there must be _something_ different than in other miners... Still no idea?

I will have CFSworks take a look at the RPC protocol implementation, since he was the one who worked on that part of Phoenix. I mostly understand how it works, but if I can't see this problem occur for myself I don't know where to start.

We might end up needing to give you a modified build that logs additional info when this happens if we can't find the problem.
Pages:
Jump to: