Skip to content
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

cmd/compile: swapping two elements of a slice generates double the necessary boundary checks #10131

Closed
brtzsnr opened this issue Mar 11, 2015 · 9 comments

Comments

@brtzsnr
Copy link
Contributor

brtzsnr commented Mar 11, 2015

For the following code:

type slice []int
func (s slice) swap(i, j int) {
  s[i], s[j] = s[j], s[i]
}

x86 6g 1.4.1 generates:

    movq    "".s+0(FP),BX
    movq    "".i+24(FP),BP
    movq    "".s+8(FP),R8
    cmpq    BP,R8
    call    ,$runtime.panicindex·f+0(SB)
    undef   ,
    leaq    BP,BX
    movq    (BX),BP
    movq    BP,"".autotmp_0000+0(SP)
    movq    "".s+0(FP),BX
    movq    "".i+24(FP),BP
    movq    "".s+8(FP),R8
    cmpq    BP,R8
    call    ,$runtime.panicindex·f+0(SB)
    undef   ,
    leaq    BP,BX
    movq    "".s+0(FP),BP
    movq    "".j+32(FP),R8
    movq    "".s+8(FP),R9
    cmpq    R8,R9
    call    ,$runtime.panicindex·f+0(SB)
    undef   ,
    leaq    R8,BP
    movq    (BP),R8
    movq    R8,(BX)
    movq    "".s+0(FP),BX
    movq    "".j+32(FP),BP
    movq    "".s+8(FP),R8
    cmpq    BP,R8
    call    ,$runtime.panicindex·f+0(SB)
    undef   ,
    leaq    BP,BX
    movq    "".autotmp_0000+0(SP),BP
    movq    BP,(BX)

This is double than the necessary boundary checks. Moreover, in the best case there should be only a boundary check for max(i, j).

@brtzsnr
Copy link
Contributor Author

brtzsnr commented Mar 11, 2015

Another example:

type slice []int
func swap(x slice) {
  x[0], x[1] = x[1], x[0]
}

Should generate a single boundary check, not 4.

@griesemer
Copy link
Contributor

This may be worthwhile a custom optimization. It would seem that this should have a significant impact on the performance of sort.Sort calls.

@minux
Copy link
Member

minux commented Mar 11, 2015 via email

@griesemer
Copy link
Contributor

I'm aware of the single unsigned compare trick. I also expect that a good SSA backend would take care of it.

But it may be worthwhile a custom optimization in the meantime; depending on the gain (perhaps it's not significant) and the importance of sorting.

@minux
Copy link
Member

minux commented Mar 11, 2015 via email

@griesemer
Copy link
Contributor

Yes, the latter (compiler checks for swap idiom). I know that we generally eschew these kinds of optimizations (in favor of more general optimizations), but it may be easy enough (not sure though) and perhaps the win is high (sorting is reasonably important). Or in other words: I'm advocating it's worthwhile an experiment for somebody who wants to play with it. The outcome of that experiment may inform us about whether it's worthwhile or not keeping the optimization.

@brtzsnr
Copy link
Contributor Author

brtzsnr commented Mar 11, 2015

With the unsigned trick max(i, j) works for negative numbers too. max(-i,+j) = -i, max(-i, -j) = -min(i, j). In both cases it returns a negative number.

@mikioh mikioh changed the title swapping two elements of a slice generates double the necessary boundary checks cmd/nternal/gc: swapping two elements of a slice generates double the necessary boundary checks Mar 16, 2015
@mikioh mikioh changed the title cmd/nternal/gc: swapping two elements of a slice generates double the necessary boundary checks cmd/internal/gc: swapping two elements of a slice generates double the necessary boundary checks Mar 16, 2015
@rsc rsc modified the milestones: Unplanned, Go1.5Maybe Apr 10, 2015
@rsc rsc changed the title cmd/internal/gc: swapping two elements of a slice generates double the necessary boundary checks cmd/compile: swapping two elements of a slice generates double the necessary boundary checks Jun 8, 2015
@rsc
Copy link
Contributor

rsc commented Jun 29, 2015

Too late for Go 1.5.

@rsc rsc modified the milestones: Unplanned, Go1.5Maybe Jun 29, 2015
@josharian josharian self-assigned this Jun 29, 2015
@brtzsnr
Copy link
Contributor Author

brtzsnr commented Apr 1, 2016

This is fixed now. Only two bound checks are generated.

@brtzsnr brtzsnr closed this as completed Apr 1, 2016
@golang golang locked and limited conversation to collaborators Apr 2, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants