Re: [go-nuts] Where is the middle of Brazil?

2019-12-01 Thread JuciÊ Andrade
Michael, let me tell you I feel very much honored because you answered my
question right away. Thank you very much. To be honest, that was not
exactly the position I was after. Maybe my question should have been more
clear. To be effectively in the middle of our territory, the position would
divide Brazil so that half of our country area would be to the north and
half to the south, while half would be to the west and half to the east.

Andrew, the solution doesn't involve cracking the digest at all. As I said
above, maybe I should have been clearer in my question. That digest is only
to prove I already have the solution. In case someone challenges me to show
it I can send to this person a file that produced the digest.

Rodolfo, I am not crazy, man, LOL. That is a programming challenge.

Thank you my friends for your attention. Have a nice day.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALK_QV%2BwWFgU%2BLJXwkmSXd6THGd8o6D4gYzc9WU6YQnY3dQKeg%40mail.gmail.com.


Re: [go-nuts] Where is the middle of Brazil?

2019-12-01 Thread Dan Kortschak
This looks like a job for geocrypt :)

https://godoc.org/github.com/kortschak/geocrypt

On Sun, 2019-12-01 at 06:37 -0300, JuciÊ Andrade wrote:
> Andrew, the solution doesn't involve cracking the digest at all. As I
> said above, maybe I should have been clearer in my question. That
> digest is only to prove I already have the solution. In case someone
> challenges me to show it I can send to this person a file that
> produced the digest.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b18b09f9f688f10ae20f098b35300fd4074916b8.camel%40kortschak.io.


[go-nuts] Re: ? How restrict usage of packages ?

2019-12-01 Thread Daniel Norte Moraes
Good Point!

Really Thanks! :-)

Em segunda-feira, 25 de novembro de 2019 14:44:10 UTC-3, JuciÊ Andrade 
escreveu:
>
> Add a script to your users continuous integration tool or even to their 
> source control management.
> Whenever software is compiled or commited your script will search for 
> imports in Go source files.
> If your script finds a forbidden package it should flag an error with a 
> friendly message like this:
>
> "You are NOT supposed to write full blown Go, but only Daniel's NearlyGo, 
> that nowadays disallows importing package X, for your own good. In case you 
> get angry please take out your pants and jump vigorously stepping on it 
> again and again until you have your rage diminished somewhat. Only then, 
> contact Daniel."
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9189eebb-0d75-483f-af85-7a6c26d4d962%40googlegroups.com.


[go-nuts] Re: ? How restrict usage of packages ?

2019-12-01 Thread Daniel Norte Moraes


Em segunda-feira, 25 de novembro de 2019 21:39:30 UTC-3, Scott Pakin 
escreveu:
>
> On Monday, November 25, 2019 at 9:55:55 AM UTC-7, Daniel Norte Moraes 
> wrote:
>>
>>I Want create and permite my users to create go lang programs mostly 
>> with full capabilities from
>> golang itself, but with some direct capabilities as net and filesystem 
>> striped from direct accesss; mostly 
>> capabilities as database access, and network access will be encapsuled in 
>> ours third parthy golang libs :-)
>>   The intent is use golang as a full-fledge compiled language and as 
>> substitute for a need a custom scripted language.
>>
>
> I do something much like that for my Go Server Pages 
>  project, which lets one embed Go code in a Web 
> page à la PHP.  The Web server administrator can choose which packages are 
> allowed to be imported, with the default being only the provided gosp 
> package , which 
> encapsulates a few functions from some of the standard packages.  Check out 
> the gosp2go source directory 
>  and in 
> particular the ValidateImports method in utils.go 
> 
> .
>
> — Scott
>


Uau!!! Thanks a Lot! :-D

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f7503fa4-2c36-4770-8550-88326a9535c6%40googlegroups.com.


Re: [go-nuts] C variadic macro equivalent in Golang?

2019-12-01 Thread minforth
That did it:

// --- variad.go -- variadic function test

package main
import("fmt";"os")

// flags
var df,ef int = 1,1

// variadic function thru empty interface
func PR(f string, a ...interface{}) {
if df!=0 { fmt.Printf(f, a...)
   if ef!=0 { fmt.Fprintf(os.Stderr,f, a...) } }
}

func main() { // should print:  -- -- 1 a 1 1 a 1
   PR("-- ")
   PR("%d a %d ",df,ef)
}

// --- End

Thanks a lot to everybody !!   


Am Sonntag, 1. Dezember 2019 03:00:03 UTC+1 schrieb Bakul Shah:
>
> func PR(f string, a ...interface{}) {
> if d { return }
> fmt.Fprintf(os.Stderr, f, a...)
> }
>
> Add appropriate imports. 
>
>
> On Nov 30, 2019, at 12:08 PM, minf...@arcor.de  wrote:
>
> C allows comma-separated argument lists via variadic macros. Whereas AFAIK 
> golang allows only variadic arguments of the same type.
> (Please excuse if I am wrong, I am considering myself a golang newbie)
>
> C demo program that prints:   -- -- 1 and 1 1 and 1
>
> // ## C variadic macro test
>
> #include 
>
> #define PR(...) if(df){printf(__VA_ARGS__);\
> if(ef)fprintf(stderr,__VA_ARGS__);}
>
> // Flags
> int df=1, ef=1;
>
> int main(void) {
>   PR("-- ");
>   PR("%d and %d ",df,ef);
> }
>
> // ## End
>
> How would one implement an equivalent PR(...) "function" in Go ???
>
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golan...@googlegroups.com .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/e36eb032-ffbc-4b26-8c41-f76aa6dcdd00%40googlegroups.com
>  
> 
> .
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ee90bef1-60c9-4f77-bf74-f9afa5080c22%40googlegroups.com.


[go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Vital Nabokov
Разбить массив чисел на два массива?
Split an array of numbers into two arrays?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/dc7702b6-9b12-4e2a-9295-78e821836ee5%40googlegroups.com.


Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Marcin Romaszewicz
It's very simple to do that:
https://play.golang.org/p/1i7pI2OXmej



On Sun, Dec 1, 2019 at 8:22 AM Vital Nabokov  wrote:

> Разбить массив чисел на два массива?
> Split an array of numbers into two arrays?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/dc7702b6-9b12-4e2a-9295-78e821836ee5%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LvDdnipcTmp2_n9Lzbx0rob5JKnFgvuv93r-AJvwsMnAg%40mail.gmail.com.


Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Daniela Petruzalek
I'm not sure if that is a good idea 😅

https://play.golang.org/p/Mj77pgsaVsB

Daniela Petruzalek
Software Engineer
github.com/danicat
twitter.com/danicat83


Em dom., 1 de dez. de 2019 às 17:07, Marcin Romaszewicz 
escreveu:

> It's very simple to do that:
> https://play.golang.org/p/1i7pI2OXmej
>
>
>
> On Sun, Dec 1, 2019 at 8:22 AM Vital Nabokov 
> wrote:
>
>> Разбить массив чисел на два массива?
>> Split an array of numbers into two arrays?
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/dc7702b6-9b12-4e2a-9295-78e821836ee5%40googlegroups.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LvDdnipcTmp2_n9Lzbx0rob5JKnFgvuv93r-AJvwsMnAg%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2B%3DiygvfM4KFGMiHDF-VAqXi1w%3D%3D5F7HRgM2oA65OaFUtY-KKQ%40mail.gmail.com.


Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Marcin Romaszewicz
Well, in that case: https://play.golang.org/p/DhSC_xF0jPW  :)



On Sun, Dec 1, 2019 at 12:34 PM Daniela Petruzalek <
daniela.petruza...@gmail.com> wrote:

> I'm not sure if that is a good idea 😅
>
> https://play.golang.org/p/Mj77pgsaVsB
>
> Daniela Petruzalek
> Software Engineer
> github.com/danicat
> twitter.com/danicat83
>
>
> Em dom., 1 de dez. de 2019 às 17:07, Marcin Romaszewicz 
> escreveu:
>
>> It's very simple to do that:
>> https://play.golang.org/p/1i7pI2OXmej
>>
>>
>>
>> On Sun, Dec 1, 2019 at 8:22 AM Vital Nabokov 
>> wrote:
>>
>>> Разбить массив чисел на два массива?
>>> Split an array of numbers into two arrays?
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/dc7702b6-9b12-4e2a-9295-78e821836ee5%40googlegroups.com
>>> 
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LvDdnipcTmp2_n9Lzbx0rob5JKnFgvuv93r-AJvwsMnAg%40mail.gmail.com
>> 
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29Ltugia1prgQgOayi5xq5DcDJF2nqiS1gx62GC7fT1GFag%40mail.gmail.com.


Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Harald Weidner
Hello,

> I'm not sure if that is a good idea 😅
> https://play.golang.org/p/Mj77pgsaVsB

This is why three-index slices were added in Go 1.2.

https://play.golang.org/p/_sJ9OKWsvMz

https://golang.org/doc/go1.2#three_index

Regards,
Harald

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/20191201210651.v4a2cjgorkeqnap2%40hweidner.de.


Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Michael Jones
Oh! That's just a bit per integer in the test range 0..total-1. Since Go
(and everything else) lacks a bit type, I just type such code
automatically. Bytes hold 8 bits. Array size must be rounded up, so

a := make([]byte, (total+8-1)/8)

array index for test integer n is n/8, so "n>>3"

bit index for the j-th bit, counting up from 0 for the 1's place is "1<>3] & mask != 0

to set it is

a[n>>3] |= mask

the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using
64-bit ints they become 6 and 64.

On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:

> I wrote a less-sophisticated version of your test, then realized I'd
> misspent my time; all I needed was to change the atomic.Add*() to a
> mutex-protected counter, and see whether my app still failed; it did.
>
> But since you took the trouble, I read your code, and would like to
> understand your collision detector. Could you explain this bit?
>
> for _, v := range a {
>   mask := byte(1 << (v & (8 - 1)))
>   index := v >> 3
>
>   if tally[index]&mask != 0 { ... }
>   ...
> }
>
> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
>>
>> As a follow-up, some more timing:
>>
>> *47088064 atomic increments/sec (my original email above for heavy
>> synchronization conflict incrementing)*
>>
>> 142049067 atomic increments/sec when each goroutine has its own atomic
>> update target. (Not testing global synchronization/mutex, just the
>> overhead of congested vs not.)
>>
>> 426232527 ordinary "x++" increments in the workers.
>>
>> General idea to remember:
>>
>> Atomic increment is ~3x slower than simple add when uncontested.
>> Highly contested atomic increment is ~3x closer than uncontested,
>> therefore ~9x-10x slower than simple add.
>>
>> 10x is not insignificant, but is nevertheless remarkable for a reliable
>> atomic operation. This was once, "back in the day", a remarkably expensive
>> operation, an a feat of genius to accomplish (Dekker's Algorithm
>> ). That it is now
>> just a number-of-fingers cycles is fantastic progress!
>>
>> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones 
>> wrote:
>>
>>> Liam,
>>>
>>> I just wrote a little stress test program for you. Maybe it will make
>>> you less stressed. ;-)
>>> https://play.golang.org/p/5_7Geyczd1V
>>>
>>> 4 CPU 2016 MacBook Pro:
>>>
>>> *celeste:atom mtj$ go run main.go*
>>> *32 concurrent workers*
>>> *128 batches of 1048576 atomic increments, 134217728 total increments*
>>> *2.850 seconds elapsed, 47088064 atomic increments/sec*
>>> *0 collisions*
>>>
>>>
>>> 18 CPU 2019 iMacPro:
>>>
>>> *plum:atom mtj$ go run main.go*
>>> *32 concurrent workers*
>>> *128 batches of 1048576 atomic increments, 134217728 total increments*
>>> *2.730 seconds elapsed, 49167382 atomic increments/sec*
>>> *0 collisions*
>>>
>>>
>>> Exhaustive demonstration is no proof, but changing the parameters here
>>> may increase your comfort.
>>>
>>> Michael
>>>
>>> On Sat, Nov 30, 2019 at 1:02 PM Robert Engels 
>>> wrote:
>>>
 If this was broken I think a lot of things would break.

 On Nov 30, 2019, at 1:56 PM, Liam  wrote:

 
 The stress test for my app fails frequently with what looks like a
 collision in atomic.AddUint64() results, so I wondered whether I had
 misunderstood atomic-add.

 So far I can't reproduce it with a small program, so I've probably
 misunderstood my app :-)

 On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>
> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
>
>> Does atomic.AddInt32(&x, 1) always yield unique values for concurrent
>> callers?
>>
>> I'm guessing not, because (I think) I'm seeing that two callers get
>> x+2, neither gets x+1.
>>
>
> That shouldn't happen, AFAICT. Can you share the code where the
> incorrect behavior is occurring? Or, preferably, a simple reproducer
> program?
>
>
>> Is there a way to generate unique values with pkg atomic, or is a
>> mutex required?
>>
>
> Keep in mind that atomic.AddInt32() has the usual two's-complement
> overflow semantics. If all you want is a generation counter you really
> should be using a uint32 and atomic.AddUint32(). Also, depending on your
> preferences and performance considerations you might find it preferable to
> use a channel that holds a single int, or small number of ints, that is 
> fed
> by a producer goroutine and consumed by any context needing a uniq ID. 
> That
> makes it easier to abstract the generation of "unique" ints so that they
> satisfy other constraints (e.g., they must be even, odd, prime, etc.).
>
> --
> Kurtis Rader
> Caretaker of the exceptional canines Junior and Hank
>
 --
 You received this message because you are subscribed to the Google
 Groups "golang-nuts" group.
 To unsubscribe from this group and stop receiving emails from

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread robert engels
I’d prefer v / 8 over v >> 3 - provides more context in my opinion. The 
compiler will change to right shift if more efficient anyway.

> On Dec 1, 2019, at 4:21 PM, Michael Jones  wrote:
> 
> Oh! That's just a bit per integer in the test range 0..total-1. Since Go (and 
> everything else) lacks a bit type, I just type such code automatically. Bytes 
> hold 8 bits. Array size must be rounded up, so
> 
> a := make([]byte, (total+8-1)/8)
> 
> array index for test integer n is n/8, so "n>>3"
> 
> bit index for the j-th bit, counting up from 0 for the 1's place is "1< 
> j is n%8, so "n&(8-1)"
> 
> if mask=1<<(n&(8-1)) then one can test if the bit is set with
> 
> a[n>>3] & mask != 0
> 
> to set it is 
> 
> a[n>>3] |= mask
> 
> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using 
> 64-bit ints they become 6 and 64. 
> 
> On Sat, Nov 30, 2019 at 7:06 PM Liam  > wrote:
> I wrote a less-sophisticated version of your test, then realized I'd misspent 
> my time; all I needed was to change the atomic.Add*() to a mutex-protected 
> counter, and see whether my app still failed; it did.
> 
> But since you took the trouble, I read your code, and would like to 
> understand your collision detector. Could you explain this bit?
> 
> for _, v := range a {
>   mask := byte(1 << (v & (8 - 1))) 
>   index := v >> 3
> 
>   if tally[index]&mask != 0 { ... }
>   ...
> }
> 
> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
> As a follow-up, some more timing:
> 
> 47088064 atomic increments/sec (my original email above for heavy 
> synchronization conflict incrementing)
> 
> 142049067 atomic increments/sec when each goroutine has its own atomic update 
> target. (Not testing global synchronization/mutex, just the overhead of 
> congested vs not.)
> 
> 426232527 ordinary "x++" increments in the workers.
> 
> General idea to remember:
> 
> Atomic increment is ~3x slower than simple add when uncontested.
> Highly contested atomic increment is ~3x closer than uncontested, therefore 
> ~9x-10x slower than simple add.
> 
> 10x is not insignificant, but is nevertheless remarkable for a reliable 
> atomic operation. This was once, "back in the day", a remarkably expensive 
> operation, an a feat of genius to accomplish (Dekker's Algorithm 
> ). That it is now just a 
> number-of-fingers cycles is fantastic progress!
> 
> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones > wrote:
> Liam,
> 
> I just wrote a little stress test program for you. Maybe it will make you 
> less stressed. ;-)
> https://play.golang.org/p/5_7Geyczd1V 
> 
> 4 CPU 2016 MacBook Pro:
> celeste:atom mtj$ go run main.go
> 32 concurrent workers
> 128 batches of 1048576 atomic increments, 134217728 total increments
> 2.850 seconds elapsed, 47088064 atomic increments/sec
> 0 collisions
> 
> 18 CPU 2019 iMacPro:
> plum:atom mtj$ go run main.go
> 32 concurrent workers
> 128 batches of 1048576 atomic increments, 134217728 total increments
> 2.730 seconds elapsed, 49167382 atomic increments/sec
> 0 collisions
> 
> Exhaustive demonstration is no proof, but changing the parameters here may 
> increase your comfort.
> 
> Michael
> 
> On Sat, Nov 30, 2019 at 1:02 PM Robert Engels > wrote:
> If this was broken I think a lot of things would break. 
> 
>> On Nov 30, 2019, at 1:56 PM, Liam > wrote:
>> 
>> 
>> The stress test for my app fails frequently with what looks like a collision 
>> in atomic.AddUint64() results, so I wondered whether I had misunderstood 
>> atomic-add.
>> 
>> So far I can't reproduce it with a small program, so I've probably 
>> misunderstood my app :-)
>> 
>> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>> On Fri, Nov 29, 2019 at 6:21 PM Liam > wrote:
>> Does atomic.AddInt32(&x, 1) always yield unique values for concurrent 
>> callers?
>> 
>> I'm guessing not, because (I think) I'm seeing that two callers get x+2, 
>> neither gets x+1.
>> 
>> That shouldn't happen, AFAICT. Can you share the code where the incorrect 
>> behavior is occurring? Or, preferably, a simple reproducer program?
>>   
>> Is there a way to generate unique values with pkg atomic, or is a mutex 
>> required?
>> 
>> Keep in mind that atomic.AddInt32() has the usual two's-complement  overflow 
>> semantics. If all you want is a generation counter you really should be 
>> using a uint32 and atomic.AddUint32(). Also, depending on your preferences 
>> and performance considerations you might find it preferable to use a channel 
>> that holds a single int, or small number of ints, that is fed by a producer 
>> goroutine and consumed by any context needing a uniq ID. That makes it 
>> easier to abstract the generation of "unique" ints so that they satisfy 
>> other constraints (e.g., they must be even, odd, prime, etc.).
>> 
>> -- 
>> Kurtis Rader
>> Caretaker of the exceptional canines Junior and Hank
>> 
>> 

Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Bakul Shah
On Dec 1, 2019, at 1:06 PM, Harald Weidner  wrote:
> 
> Hello,
> 
>> I'm not sure if that is a good idea 😅
>> https://play.golang.org/p/Mj77pgsaVsB
> 
> This is why three-index slices were added in Go 1.2.
> 
> https://play.golang.org/p/_sJ9OKWsvMz
> 
> https://golang.org/doc/go1.2#three_index

Unfortunately a[i:j:k] acts exactly like a[i:j] if i+k >= cap(a)
and appending to subslice can mutate the underlying slice.

See https://play.golang.org/p/ppWob2yJDiS

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/024223E8-0EDE-485B-929C-A14FA42A96FF%40bitblocks.com.


Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Michael Jones
agree, makes sense. also if you trust the compiler, change to use the mod
function, etc.

On Sun, Dec 1, 2019 at 2:31 PM robert engels  wrote:

> I’d prefer v / 8 over v >> 3 - provides more context in my opinion. The
> compiler will change to right shift if more efficient anyway.
>
> On Dec 1, 2019, at 4:21 PM, Michael Jones  wrote:
>
> Oh! That's just a bit per integer in the test range 0..total-1. Since Go
> (and everything else) lacks a bit type, I just type such code
> automatically. Bytes hold 8 bits. Array size must be rounded up, so
>
> a := make([]byte, (total+8-1)/8)
>
> array index for test integer n is n/8, so "n>>3"
>
> bit index for the j-th bit, counting up from 0 for the 1's place is "1<
> j is n%8, so "n&(8-1)"
>
> if mask=1<<(n&(8-1)) then one can test if the bit is set with
>
> a[n>>3] & mask != 0
>
> to set it is
>
> a[n>>3] |= mask
>
> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using
> 64-bit ints they become 6 and 64.
>
> On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:
>
>> I wrote a less-sophisticated version of your test, then realized I'd
>> misspent my time; all I needed was to change the atomic.Add*() to a
>> mutex-protected counter, and see whether my app still failed; it did.
>>
>> But since you took the trouble, I read your code, and would like to
>> understand your collision detector. Could you explain this bit?
>>
>> for _, v := range a {
>>   mask := byte(1 << (v & (8 - 1)))
>>   index := v >> 3
>>
>>   if tally[index]&mask != 0 { ... }
>>   ...
>> }
>>
>> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
>>>
>>> As a follow-up, some more timing:
>>>
>>> *47088064 atomic increments/sec (my original email above for heavy
>>> synchronization conflict incrementing)*
>>>
>>> 142049067 atomic increments/sec when each goroutine has its own atomic
>>> update target. (Not testing global synchronization/mutex, just the
>>> overhead of congested vs not.)
>>>
>>> 426232527 ordinary "x++" increments in the workers.
>>>
>>> General idea to remember:
>>>
>>> Atomic increment is ~3x slower than simple add when uncontested.
>>> Highly contested atomic increment is ~3x closer than uncontested,
>>> therefore ~9x-10x slower than simple add.
>>>
>>> 10x is not insignificant, but is nevertheless remarkable for a reliable
>>> atomic operation. This was once, "back in the day", a remarkably expensive
>>> operation, an a feat of genius to accomplish (Dekker's Algorithm
>>> ). That it is now
>>> just a number-of-fingers cycles is fantastic progress!
>>>
>>> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones 
>>> wrote:
>>>
 Liam,

 I just wrote a little stress test program for you. Maybe it will make
 you less stressed. ;-)
 https://play.golang.org/p/5_7Geyczd1V

 4 CPU 2016 MacBook Pro:

 *celeste:atom mtj$ go run main.go*
 *32 concurrent workers*
 *128 batches of 1048576 atomic increments, 134217728 total increments*
 *2.850 seconds elapsed, 47088064 atomic increments/sec*
 *0 collisions*


 18 CPU 2019 iMacPro:

 *plum:atom mtj$ go run main.go*
 *32 concurrent workers*
 *128 batches of 1048576 atomic increments, 134217728 total increments*
 *2.730 seconds elapsed, 49167382 atomic increments/sec*
 *0 collisions*


 Exhaustive demonstration is no proof, but changing the parameters here
 may increase your comfort.

 Michael

 On Sat, Nov 30, 2019 at 1:02 PM Robert Engels 
 wrote:

> If this was broken I think a lot of things would break.
>
> On Nov 30, 2019, at 1:56 PM, Liam  wrote:
>
> 
> The stress test for my app fails frequently with what looks like a
> collision in atomic.AddUint64() results, so I wondered whether I had
> misunderstood atomic-add.
>
> So far I can't reproduce it with a small program, so I've probably
> misunderstood my app :-)
>
> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>>
>> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
>>
>>> Does atomic.AddInt32(&x, 1) always yield unique values for
>>> concurrent callers?
>>>
>>> I'm guessing not, because (I think) I'm seeing that two callers get
>>> x+2, neither gets x+1.
>>>
>>
>> That shouldn't happen, AFAICT. Can you share the code where the
>> incorrect behavior is occurring? Or, preferably, a simple reproducer
>> program?
>>
>>
>>> Is there a way to generate unique values with pkg atomic, or is a
>>> mutex required?
>>>
>>
>> Keep in mind that atomic.AddInt32() has the usual two's-complement
>> overflow semantics. If all you want is a generation counter you really
>> should be using a uint32 and atomic.AddUint32(). Also, depending on your
>> preferences and performance considerations you might find it preferable 
>> to
>> use a channel that

Re: [go-nuts] Разбить массив чисел на два массива

2019-12-01 Thread Dan Kortschak
What do you mean by i+k >= cap(a)? k+(any non-negative number) may not
be greater than cap(a). The key to safely appending when you are unsure
of the backing array's state is to append to the slice length and
capped to the same size.

On Sun, 2019-12-01 at 14:55 -0800, Bakul Shah wrote:
> Unfortunately a[i:j:k] acts exactly like a[i:j] if i+k >= cap(a)
> and appending to subslice can mutate the underlying slice.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9788999a3d868cb34fbe1b6b59d0623dc76fe3ec.camel%40kortschak.io.


[go-nuts] Download server data in the web browser

2019-12-01 Thread 洪嘉鴻
Hello everyone:
  The version of the golang which I am using is 1.12.9 with WIn10. Now 
I'm trying to write a web browser. I've found some examples about web 
applications.
Here is the code  about the server. 
I want to download the data (which is the variable "file" in the code) in 
the browser. However, I have no idea how to write download dialog.
Is there any functions that I could use?

Any help is appreciated.
Thank you very much!
Max

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/808605c6-dc43-4527-8657-fc1f9baa10cc%40googlegroups.com.


Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Liam
Oh you've allocated a bit array for every value in the test range, then 
checked for gaps in it?

On Sunday, December 1, 2019 at 2:21:55 PM UTC-8, Michael Jones wrote:
>
> Oh! That's just a bit per integer in the test range 0..total-1. Since Go 
> (and everything else) lacks a bit type, I just type such code 
> automatically. Bytes hold 8 bits. Array size must be rounded up, so
>
> a := make([]byte, (total+8-1)/8)
>
> array index for test integer n is n/8, so "n>>3"
>
> bit index for the j-th bit, counting up from 0 for the 1's place is "1<
> j is n%8, so "n&(8-1)"
>
> if mask=1<<(n&(8-1)) then one can test if the bit is set with
>
> a[n>>3] & mask != 0
>
> to set it is 
>
> a[n>>3] |= mask
>
> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using 
> 64-bit ints they become 6 and 64. 
>
> On Sat, Nov 30, 2019 at 7:06 PM Liam > 
> wrote:
>
>> I wrote a less-sophisticated version of your test, then realized I'd 
>> misspent my time; all I needed was to change the atomic.Add*() to a 
>> mutex-protected counter, and see whether my app still failed; it did.
>>
>> But since you took the trouble, I read your code, and would like to 
>> understand your collision detector. Could you explain this bit?
>>
>> for _, v := range a {
>>   mask := byte(1 << (v & (8 - 1))) 
>>   index := v >> 3
>>
>>   if tally[index]&mask != 0 { ... }
>>   ...
>> }
>>
>> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
>>>
>>> As a follow-up, some more timing:
>>>
>>> *47088064 atomic increments/sec (my original email above for heavy 
>>> synchronization conflict incrementing)*
>>>
>>> 142049067 atomic increments/sec when each goroutine has its own atomic 
>>> update target. (Not testing global synchronization/mutex, just the 
>>> overhead of congested vs not.)
>>>
>>> 426232527 ordinary "x++" increments in the workers.
>>>
>>> General idea to remember:
>>>
>>> Atomic increment is ~3x slower than simple add when uncontested.
>>> Highly contested atomic increment is ~3x closer than uncontested, 
>>> therefore ~9x-10x slower than simple add.
>>>
>>> 10x is not insignificant, but is nevertheless remarkable for a reliable 
>>> atomic operation. This was once, "back in the day", a remarkably expensive 
>>> operation, an a feat of genius to accomplish (Dekker's Algorithm 
>>> ). That it is now 
>>> just a number-of-fingers cycles is fantastic progress!
>>>
>>> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones  
>>> wrote:
>>>
 Liam,

 I just wrote a little stress test program for you. Maybe it will make 
 you less stressed. ;-)
 https://play.golang.org/p/5_7Geyczd1V

 4 CPU 2016 MacBook Pro:

 *celeste:atom mtj$ go run main.go*
 *32 concurrent workers*
 *128 batches of 1048576 atomic increments, 134217728 total increments*
 *2.850 seconds elapsed, 47088064 atomic increments/sec*
 *0 collisions*


 18 CPU 2019 iMacPro:

 *plum:atom mtj$ go run main.go*
 *32 concurrent workers*
 *128 batches of 1048576 atomic increments, 134217728 total increments*
 *2.730 seconds elapsed, 49167382 atomic increments/sec*
 *0 collisions*


 Exhaustive demonstration is no proof, but changing the parameters here 
 may increase your comfort.

 Michael

 On Sat, Nov 30, 2019 at 1:02 PM Robert Engels  
 wrote:

> If this was broken I think a lot of things would break. 
>
> On Nov 30, 2019, at 1:56 PM, Liam  wrote:
>
> 
> The stress test for my app fails frequently with what looks like a 
> collision in atomic.AddUint64() results, so I wondered whether I had 
> misunderstood atomic-add.
>
> So far I can't reproduce it with a small program, so I've probably 
> misunderstood my app :-)
>
> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>>
>> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
>>
>>> Does atomic.AddInt32(&x, 1) always yield unique values for 
>>> concurrent callers?
>>>
>>> I'm guessing not, because (I think) I'm seeing that two callers get 
>>> x+2, neither gets x+1.
>>>
>>
>> That shouldn't happen, AFAICT. Can you share the code where the 
>> incorrect behavior is occurring? Or, preferably, a simple reproducer 
>> program?
>>   
>>
>>> Is there a way to generate unique values with pkg atomic, or is a 
>>> mutex required?
>>>
>>
>> Keep in mind that atomic.AddInt32() has the usual two's-complement  
>> overflow semantics. If all you want is a generation counter you really 
>> should be using a uint32 and atomic.AddUint32(). Also, depending on your 
>> preferences and performance considerations you might find it preferable 
>> to 
>> use a channel that holds a single int, or small number of ints, that is 
>> fed 
>> by a producer goroutine and consumed by any context 

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Robert Engels
The updating of the bit array if shared needs to atomic as well, probably with 
a read and cas.  

> On Dec 1, 2019, at 9:19 PM, Liam  wrote:
> 
> 
> Oh you've allocated a bit array for every value in the test range, then 
> checked for gaps in it?
> 
>> On Sunday, December 1, 2019 at 2:21:55 PM UTC-8, Michael Jones wrote:
>> Oh! That's just a bit per integer in the test range 0..total-1. Since Go 
>> (and everything else) lacks a bit type, I just type such code automatically. 
>> Bytes hold 8 bits. Array size must be rounded up, so
>> 
>> a := make([]byte, (total+8-1)/8)
>> 
>> array index for test integer n is n/8, so "n>>3"
>> 
>> bit index for the j-th bit, counting up from 0 for the 1's place is "1<> 
>> j is n%8, so "n&(8-1)"
>> 
>> if mask=1<<(n&(8-1)) then one can test if the bit is set with
>> 
>> a[n>>3] & mask != 0
>> 
>> to set it is 
>> 
>> a[n>>3] |= mask
>> 
>> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using 
>> 64-bit ints they become 6 and 64. 
>> 
>>> On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:
>>> I wrote a less-sophisticated version of your test, then realized I'd 
>>> misspent my time; all I needed was to change the atomic.Add*() to a 
>>> mutex-protected counter, and see whether my app still failed; it did.
>>> 
>>> But since you took the trouble, I read your code, and would like to 
>>> understand your collision detector. Could you explain this bit?
>>> 
>>> for _, v := range a {
>>>   mask := byte(1 << (v & (8 - 1))) 
>>>   index := v >> 3
>>> 
>>>   if tally[index]&mask != 0 { ... }
>>>   ...
>>> }
>>> 
 On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
 As a follow-up, some more timing:
 
 47088064 atomic increments/sec (my original email above for heavy 
 synchronization conflict incrementing)
 
 142049067 atomic increments/sec when each goroutine has its own atomic 
 update target. (Not testing global synchronization/mutex, just the 
 overhead of congested vs not.)
 
 426232527 ordinary "x++" increments in the workers.
 
 General idea to remember:
 
 Atomic increment is ~3x slower than simple add when uncontested.
 Highly contested atomic increment is ~3x closer than uncontested, 
 therefore ~9x-10x slower than simple add.
 
 10x is not insignificant, but is nevertheless remarkable for a reliable 
 atomic operation. This was once, "back in the day", a remarkably expensive 
 operation, an a feat of genius to accomplish (Dekker's Algorithm). That it 
 is now just a number-of-fingers cycles is fantastic progress!
 
> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones  wrote:
> Liam,
> 
> I just wrote a little stress test program for you. Maybe it will make you 
> less stressed. ;-)
> https://play.golang.org/p/5_7Geyczd1V
> 
> 4 CPU 2016 MacBook Pro:
> celeste:atom mtj$ go run main.go
> 32 concurrent workers
> 128 batches of 1048576 atomic increments, 134217728 total increments
> 2.850 seconds elapsed, 47088064 atomic increments/sec
> 0 collisions
> 
> 18 CPU 2019 iMacPro:
> plum:atom mtj$ go run main.go
> 32 concurrent workers
> 128 batches of 1048576 atomic increments, 134217728 total increments
> 2.730 seconds elapsed, 49167382 atomic increments/sec
> 0 collisions
> 
> Exhaustive demonstration is no proof, but changing the parameters here 
> may increase your comfort.
> 
> Michael
> 
>> On Sat, Nov 30, 2019 at 1:02 PM Robert Engels  
>> wrote:
>> If this was broken I think a lot of things would break. 
>> 
 On Nov 30, 2019, at 1:56 PM, Liam  wrote:
 
>>> 
>>> The stress test for my app fails frequently with what looks like a 
>>> collision in atomic.AddUint64() results, so I wondered whether I had 
>>> misunderstood atomic-add.
>>> 
>>> So far I can't reproduce it with a small program, so I've probably 
>>> misunderstood my app :-)
>>> 
 On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
 
> Does atomic.AddInt32(&x, 1) always yield unique values for concurrent 
> callers?
> 
> I'm guessing not, because (I think) I'm seeing that two callers get 
> x+2, neither gets x+1.
 
 That shouldn't happen, AFAICT. Can you share the code where the 
 incorrect behavior is occurring? Or, preferably, a simple reproducer 
 program?
   
> Is there a way to generate unique values with pkg atomic, or is a 
> mutex required?
 
 Keep in mind that atomic.AddInt32() has the usual two's-complement  
 overflow semantics. If all you want is a generation counter you really 
 should be using a uint32 and atomic.AddUint32(). Also, depending on 
 your preferences and performance considera

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Michael Jones
not necessary as the testing and updating is only done in one place by one
the main goroutine.

On Sun, Dec 1, 2019 at 7:46 PM Robert Engels  wrote:

> The updating of the bit array if shared needs to atomic as well, probably
> with a read and cas.
>
> On Dec 1, 2019, at 9:19 PM, Liam  wrote:
>
> 
> Oh you've allocated a bit array for every value in the test range, then
> checked for gaps in it?
>
> On Sunday, December 1, 2019 at 2:21:55 PM UTC-8, Michael Jones wrote:
>>
>> Oh! That's just a bit per integer in the test range 0..total-1. Since Go
>> (and everything else) lacks a bit type, I just type such code
>> automatically. Bytes hold 8 bits. Array size must be rounded up, so
>>
>> a := make([]byte, (total+8-1)/8)
>>
>> array index for test integer n is n/8, so "n>>3"
>>
>> bit index for the j-th bit, counting up from 0 for the 1's place is "1<>
>> j is n%8, so "n&(8-1)"
>>
>> if mask=1<<(n&(8-1)) then one can test if the bit is set with
>>
>> a[n>>3] & mask != 0
>>
>> to set it is
>>
>> a[n>>3] |= mask
>>
>> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using
>> 64-bit ints they become 6 and 64.
>>
>> On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:
>>
>>> I wrote a less-sophisticated version of your test, then realized I'd
>>> misspent my time; all I needed was to change the atomic.Add*() to a
>>> mutex-protected counter, and see whether my app still failed; it did.
>>>
>>> But since you took the trouble, I read your code, and would like to
>>> understand your collision detector. Could you explain this bit?
>>>
>>> for _, v := range a {
>>>   mask := byte(1 << (v & (8 - 1)))
>>>   index := v >> 3
>>>
>>>   if tally[index]&mask != 0 { ... }
>>>   ...
>>> }
>>>
>>> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:

 As a follow-up, some more timing:

 *47088064 atomic increments/sec (my original email above for heavy
 synchronization conflict incrementing)*

 142049067 atomic increments/sec when each goroutine has its own atomic
 update target. (Not testing global synchronization/mutex, just the
 overhead of congested vs not.)

 426232527 ordinary "x++" increments in the workers.

 General idea to remember:

 Atomic increment is ~3x slower than simple add when uncontested.
 Highly contested atomic increment is ~3x closer than uncontested,
 therefore ~9x-10x slower than simple add.

 10x is not insignificant, but is nevertheless remarkable for a reliable
 atomic operation. This was once, "back in the day", a remarkably expensive
 operation, an a feat of genius to accomplish (Dekker's Algorithm
 ). That it is now
 just a number-of-fingers cycles is fantastic progress!

 On Sat, Nov 30, 2019 at 3:38 PM Michael Jones 
 wrote:

> Liam,
>
> I just wrote a little stress test program for you. Maybe it will make
> you less stressed. ;-)
> https://play.golang.org/p/5_7Geyczd1V
>
> 4 CPU 2016 MacBook Pro:
>
> *celeste:atom mtj$ go run main.go*
> *32 concurrent workers*
> *128 batches of 1048576 atomic increments, 134217728 total increments*
> *2.850 seconds elapsed, 47088064 atomic increments/sec*
> *0 collisions*
>
>
> 18 CPU 2019 iMacPro:
>
> *plum:atom mtj$ go run main.go*
> *32 concurrent workers*
> *128 batches of 1048576 atomic increments, 134217728 total increments*
> *2.730 seconds elapsed, 49167382 atomic increments/sec*
> *0 collisions*
>
>
> Exhaustive demonstration is no proof, but changing the parameters here
> may increase your comfort.
>
> Michael
>
> On Sat, Nov 30, 2019 at 1:02 PM Robert Engels 
> wrote:
>
>> If this was broken I think a lot of things would break.
>>
>> On Nov 30, 2019, at 1:56 PM, Liam  wrote:
>>
>> 
>> The stress test for my app fails frequently with what looks like a
>> collision in atomic.AddUint64() results, so I wondered whether I had
>> misunderstood atomic-add.
>>
>> So far I can't reproduce it with a small program, so I've probably
>> misunderstood my app :-)
>>
>> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>>>
>>> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
>>>
 Does atomic.AddInt32(&x, 1) always yield unique values for
 concurrent callers?

 I'm guessing not, because (I think) I'm seeing that two callers get
 x+2, neither gets x+1.

>>>
>>> That shouldn't happen, AFAICT. Can you share the code where the
>>> incorrect behavior is occurring? Or, preferably, a simple reproducer
>>> program?
>>>
>>>
 Is there a way to generate unique values with pkg atomic, or is a
 mutex required?

>>>
>>> Keep in mind that atomic.AddInt32() has the usual two's-complement
>

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Michael Jones
"Oh you've allocated a bit array for every value in the test range, then
checked for gaps in it?"

Yes. What I should have said. (Though the test looks not for gaps but for
two pigeons in one hole, but the same idea.)

On Sun, Dec 1, 2019 at 8:44 PM Michael Jones 
wrote:

> not necessary as the testing and updating is only done in one place by one
> the main goroutine.
>
> On Sun, Dec 1, 2019 at 7:46 PM Robert Engels 
> wrote:
>
>> The updating of the bit array if shared needs to atomic as well, probably
>> with a read and cas.
>>
>> On Dec 1, 2019, at 9:19 PM, Liam  wrote:
>>
>> 
>> Oh you've allocated a bit array for every value in the test range, then
>> checked for gaps in it?
>>
>> On Sunday, December 1, 2019 at 2:21:55 PM UTC-8, Michael Jones wrote:
>>>
>>> Oh! That's just a bit per integer in the test range 0..total-1. Since Go
>>> (and everything else) lacks a bit type, I just type such code
>>> automatically. Bytes hold 8 bits. Array size must be rounded up, so
>>>
>>> a := make([]byte, (total+8-1)/8)
>>>
>>> array index for test integer n is n/8, so "n>>3"
>>>
>>> bit index for the j-th bit, counting up from 0 for the 1's place is
>>> "1<>>
>>> j is n%8, so "n&(8-1)"
>>>
>>> if mask=1<<(n&(8-1)) then one can test if the bit is set with
>>>
>>> a[n>>3] & mask != 0
>>>
>>> to set it is
>>>
>>> a[n>>3] |= mask
>>>
>>> the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using
>>> 64-bit ints they become 6 and 64.
>>>
>>> On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:
>>>
 I wrote a less-sophisticated version of your test, then realized I'd
 misspent my time; all I needed was to change the atomic.Add*() to a
 mutex-protected counter, and see whether my app still failed; it did.

 But since you took the trouble, I read your code, and would like to
 understand your collision detector. Could you explain this bit?

 for _, v := range a {
   mask := byte(1 << (v & (8 - 1)))
   index := v >> 3

   if tally[index]&mask != 0 { ... }
   ...
 }

 On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
>
> As a follow-up, some more timing:
>
> *47088064 atomic increments/sec (my original email above for heavy
> synchronization conflict incrementing)*
>
> 142049067 atomic increments/sec when each goroutine has its own atomic
> update target. (Not testing global synchronization/mutex, just the
> overhead of congested vs not.)
>
> 426232527 ordinary "x++" increments in the workers.
>
> General idea to remember:
>
> Atomic increment is ~3x slower than simple add when uncontested.
> Highly contested atomic increment is ~3x closer than uncontested,
> therefore ~9x-10x slower than simple add.
>
> 10x is not insignificant, but is nevertheless remarkable for a
> reliable atomic operation. This was once, "back in the day", a
> remarkably expensive operation, an a feat of genius to accomplish 
> (Dekker's
> Algorithm ). That
> it is now just a number-of-fingers cycles is fantastic progress!
>
> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones 
> wrote:
>
>> Liam,
>>
>> I just wrote a little stress test program for you. Maybe it will make
>> you less stressed. ;-)
>> https://play.golang.org/p/5_7Geyczd1V
>>
>> 4 CPU 2016 MacBook Pro:
>>
>> *celeste:atom mtj$ go run main.go*
>> *32 concurrent workers*
>> *128 batches of 1048576 atomic increments, 134217728 total increments*
>> *2.850 seconds elapsed, 47088064 atomic increments/sec*
>> *0 collisions*
>>
>>
>> 18 CPU 2019 iMacPro:
>>
>> *plum:atom mtj$ go run main.go*
>> *32 concurrent workers*
>> *128 batches of 1048576 atomic increments, 134217728 total increments*
>> *2.730 seconds elapsed, 49167382 atomic increments/sec*
>> *0 collisions*
>>
>>
>> Exhaustive demonstration is no proof, but changing the parameters
>> here may increase your comfort.
>>
>> Michael
>>
>> On Sat, Nov 30, 2019 at 1:02 PM Robert Engels 
>> wrote:
>>
>>> If this was broken I think a lot of things would break.
>>>
>>> On Nov 30, 2019, at 1:56 PM, Liam  wrote:
>>>
>>> 
>>> The stress test for my app fails frequently with what looks like a
>>> collision in atomic.AddUint64() results, so I wondered whether I had
>>> misunderstood atomic-add.
>>>
>>> So far I can't reproduce it with a small program, so I've probably
>>> misunderstood my app :-)
>>>
>>> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:

 On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:

> Does atomic.AddInt32(&x, 1) always yield unique values for
> concurrent callers?
>
> I'm guessing not, because (I think) I'm seeing that two callers
>>>

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Robert Engels
Sorry, I hadn’t looked at the code, but after reviewing doesn’t your code not 
detect the case where a value was skipped ? (... not that it could happen - but 
for completeness of the robust test)

> On Dec 1, 2019, at 10:44 PM, Michael Jones  wrote:
> 
> not necessary as the testing and updating is only done in one place by one 
> the main goroutine. 
> 
>> On Sun, Dec 1, 2019 at 7:46 PM Robert Engels  wrote:
>> The updating of the bit array if shared needs to atomic as well, probably 
>> with a read and cas.  
>> 
>>> On Dec 1, 2019, at 9:19 PM, Liam  wrote:
>>> 
>>> 
>>> Oh you've allocated a bit array for every value in the test range, then 
>>> checked for gaps in it?
>>> 
 On Sunday, December 1, 2019 at 2:21:55 PM UTC-8, Michael Jones wrote:
 Oh! That's just a bit per integer in the test range 0..total-1. Since Go 
 (and everything else) lacks a bit type, I just type such code 
 automatically. Bytes hold 8 bits. Array size must be rounded up, so
 
 a := make([]byte, (total+8-1)/8)
 
 array index for test integer n is n/8, so "n>>3"
 
 bit index for the j-th bit, counting up from 0 for the 1's place is "1<>>> 
 j is n%8, so "n&(8-1)"
 
 if mask=1<<(n&(8-1)) then one can test if the bit is set with
 
 a[n>>3] & mask != 0
 
 to set it is 
 
 a[n>>3] |= mask
 
 the values 3 and 8 here are from 8 bits in a byte and 8 = 2**3. if using 
 64-bit ints they become 6 and 64. 
 
> On Sat, Nov 30, 2019 at 7:06 PM Liam  wrote:
> I wrote a less-sophisticated version of your test, then realized I'd 
> misspent my time; all I needed was to change the atomic.Add*() to a 
> mutex-protected counter, and see whether my app still failed; it did.
> 
> But since you took the trouble, I read your code, and would like to 
> understand your collision detector. Could you explain this bit?
> 
> for _, v := range a {
>   mask := byte(1 << (v & (8 - 1))) 
>   index := v >> 3
> 
>   if tally[index]&mask != 0 { ... }
>   ...
> }
> 
>> On Saturday, November 30, 2019 at 5:33:50 PM UTC-8, Michael Jones wrote:
>> As a follow-up, some more timing:
>> 
>> 47088064 atomic increments/sec (my original email above for heavy 
>> synchronization conflict incrementing)
>> 
>> 142049067 atomic increments/sec when each goroutine has its own atomic 
>> update target. (Not testing global synchronization/mutex, just the 
>> overhead of congested vs not.)
>> 
>> 426232527 ordinary "x++" increments in the workers.
>> 
>> General idea to remember:
>> 
>> Atomic increment is ~3x slower than simple add when uncontested.
>> Highly contested atomic increment is ~3x closer than uncontested, 
>> therefore ~9x-10x slower than simple add.
>> 
>> 10x is not insignificant, but is nevertheless remarkable for a reliable 
>> atomic operation. This was once, "back in the day", a remarkably 
>> expensive operation, an a feat of genius to accomplish (Dekker's 
>> Algorithm). That it is now just a number-of-fingers cycles is fantastic 
>> progress!
>> 
>>> On Sat, Nov 30, 2019 at 3:38 PM Michael Jones  
>>> wrote:
>>> Liam,
>>> 
>>> I just wrote a little stress test program for you. Maybe it will make 
>>> you less stressed. ;-)
>>> https://play.golang.org/p/5_7Geyczd1V
>>> 
>>> 4 CPU 2016 MacBook Pro:
>>> celeste:atom mtj$ go run main.go
>>> 32 concurrent workers
>>> 128 batches of 1048576 atomic increments, 134217728 total increments
>>> 2.850 seconds elapsed, 47088064 atomic increments/sec
>>> 0 collisions
>>> 
>>> 18 CPU 2019 iMacPro:
>>> plum:atom mtj$ go run main.go
>>> 32 concurrent workers
>>> 128 batches of 1048576 atomic increments, 134217728 total increments
>>> 2.730 seconds elapsed, 49167382 atomic increments/sec
>>> 0 collisions
>>> 
>>> Exhaustive demonstration is no proof, but changing the parameters here 
>>> may increase your comfort.
>>> 
>>> Michael
>>> 
 On Sat, Nov 30, 2019 at 1:02 PM Robert Engels  
 wrote:
 If this was broken I think a lot of things would break. 
 
> On Nov 30, 2019, at 1:56 PM, Liam  wrote:
> 
> 
> The stress test for my app fails frequently with what looks like a 
> collision in atomic.AddUint64() results, so I wondered whether I had 
> misunderstood atomic-add.
> 
> So far I can't reproduce it with a small program, so I've probably 
> misunderstood my app :-)
> 
>> On Friday, November 29, 2019 at 6:41:39 PM UTC-8, Kurtis Rader wrote:
>>> On Fri, Nov 29, 2019 at 6:21 PM Liam  wrote:
>> 
>>> Does atomic.AddInt32(&x, 1) always yield unique values for 
>>> concurrent callers?
>>> 
>>> I'm guessing not, because 

Re: [go-nuts] atomic.Add*() doesn't produce unique values

2019-12-01 Thread Michael Jones
true. not roust that way. also, it uses "Go array bounds checking" as the
implicit test for crazy out of range values. just a 5 min stream of
consciousness hack to defend the honor of the Go atomic primitives. ;-) It
was typed one handed while the the other propped up my macbook here in bed.
easily improved.

in fact, i did improve it after sending that original email. i added outer
loops to time repeatedly, and above that, to iterate across numbers of
workers. also added an option to have the workers do a little work between
atomic operations just to see the expected "atomic cost in the noise" by
direct experience...

...works great, scales well.

4cpu+4smt cpus
celeste:atom mtj$ time atom
  1 workers, 256 batches of 131072 atomic increments, 33554432 total
increments: 18.21601 sec
  2 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  9.44632 sec
  3 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  6.77645 sec
  4 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  5.07302 sec
  5 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  4.54578 sec
  6 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  3.59711 sec
  7 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  3.21376 sec
  8 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  2.98081 sec

18+18
xplum:atom mtj$ time atom
  1 workers, 256 batches of 131072 atomic increments, 33554432 total
increments: 15.36729 sec
  2 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  8.05586 sec
  3 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  5.71047 sec
  4 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  4.25619 sec
  5 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  3.50413 sec
  6 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  2.95954 sec
  7 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  2.57278 sec
  8 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  2.29949 sec
  9 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  2.14102 sec
 10 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.96580 sec
 11 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.86208 sec
 12 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.75674 sec
 13 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.67355 sec
 14 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.60104 sec
 15 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.55347 sec
 16 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.46876 sec
 17 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.47974 sec
 18 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.46271 sec
 19 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.42377 sec
 20 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.37417 sec
 21 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.38023 sec
 22 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.32782 sec
 23 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.33747 sec
 24 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.27842 sec
 25 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.27863 sec
 26 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.22864 sec
 27 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.21858 sec
 28 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.21807 sec
 29 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.16772 sec
 30 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.15762 sec
 31 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.15192 sec
 32 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.10269 sec
 33 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.09875 sec
 34 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.09120 sec
 35 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.08135 sec
 36 workers, 256 batches of 131072 atomic increments, 33554432 total
increments:  1.09140 sec


On Sun, Dec 1, 2019 at 10:14 PM Robert Engels  wrote:

> Sorry, I hadn’t looked at the code, but after reviewing doesn’t your co