Skip to content

Still another array access performance issue (in debug) #15685

Description

@IntegratedQuantum

Zig Version

0.11.0-dev.3105+e46d7a369

Steps to Reproduce and Observed Behavior

This is a follow-up to #13938 which was only fixed in release mode(which means I still have to rely on the workaround to be able to run my code in debug mode). The reproduction code is basically identical:

const std = @import("std");

const len = 32*32*32;

fn getIndex(i: u16) u16 {
	return i;
}

pub const Chunk = struct {
	blocks: [len]u16 = undefined,
};

pub noinline fn regenerateMainMesh(chunk: *Chunk) u32 {
	var sum: u32 = 0;
	var i: u16 = 0;
	while(i < len) : (i += 1) {
		sum += chunk.blocks[getIndex(i)]; // ← workaround: (&chunk.blocks)[...]
	}
	return sum;
}

pub fn main() void {
	var chunk: Chunk = Chunk{};
	for(&chunk.blocks, 0..) |*block, i| {
		block.* = @intCast(i);
	}
	const start = std.time.nanoTimestamp();
	const sum = regenerateMainMesh(&chunk);
	const end = std.time.nanoTimestamp();
	std.log.err("Time: {} Sum: {}", .{end - start, sum});
}

Running this in debug mode is taking 93 ms for iterating over a 32768 element array:

$ zig run test.zig
error: Time: 93325090 Sum: 536854528

Running this in a profiler, I can see that the bottleneck still is a memcpy that is called once every iteration and appears to be copying the entire array:
Screenshot at 2023-05-13 10-14-00
Screenshot at 2023-05-13 10-08-58

Expected Behavior

When applying the workaround

- sum += chunk.blocks[getIndex(i)]; // ← workaround: (&chunk.blocks)[...]
+ sum += (&chunk.blocks)[getIndex(i)]; // ← workaround: (&chunk.blocks)[...]

the performance is significantly better, taking only 0.4 ms instead of 93 ms:

$ zig run test.zig
error: Time: 357398 Sum: 536854528

Activity

  1. added
    bugObserved behavior contradicts documented or intended behavior
    on May 13, 2023
  2. added this to the 0.12.0 milestone on May 13, 2023
  3. IntegratedQuantum commented on Jun 6, 2023

    @IntegratedQuantum
    ContributorAuthor

    I just updated my zig version and the problem got a lot worse.

    EDIT: I updated again and it is now back to how it was originally.

    Expand

    This simplified example was not affected in the past:

    const std = @import("std");
    
    const len = 32*32*32;
    
    var blocks: [len]u16 = undefined;
    
    pub noinline fn regenerateMainMesh() u32 {
    	var sum: u32 = 0;
    	var i: u16 = 0;
    	while(i < len) : (i += 1) {
    		sum += blocks[i]; // ← workaround: (&blocks)[...]
    	}
    	return sum;
    }
    
    pub fn main() void {
    	for(&blocks, 0..) |*block, i| {
    		block.* = @intCast(u16, i);
    	}
    	const start = std.time.nanoTimestamp();
    	const sum = regenerateMainMesh();
    	const end = std.time.nanoTimestamp();
    	std.log.err("Time: {} Sum: {}", .{end - start, sum});
    }

    But now it is also slow:

    $ zig version
    0.11.0-dev.3380+7e0a02ee2
    $ zig run test.zig
    error: Time: 98298061 Sum: 536854528
    
    $ ~/Downloads/zig-old/zig version
    0.11.0-dev.3132+465272921
    $ ~/Downloads/zig-old/zig run test.zig
    error: Time: 632556 Sum: 536854528
    
  4. modified the milestones: 0.14.0, 0.12.0 on Oct 24, 2023
  5. andrewrk commented on Jan 24, 2024

    @andrewrk
    Member

    Fix landed in 2ab7893.

  6. andrewrk commented on Jan 24, 2024

    @andrewrk
    Member

    Fix reverted in 9d5a133.

  7. added 2 commits that reference this issue on Mar 18, 2024
    9582850
    a1e1177
  8. modified the milestones: 0.12.0, 0.13.0 on Mar 20, 2024
  9. added a commit that references this issue on Mar 22, 2024
    4a167bb
  10. moved this to Optimize Machine Code in Performanceon Aug 22, 2024
  11. modified the milestones: 0.14.0, 0.14.1 on Mar 1, 2025
  12. modified the milestones: 0.14.1, 0.15.0 on Apr 15, 2025
  13. IntegratedQuantum commented on Sep 21, 2025

    @IntegratedQuantum
    ContributorAuthor

    fixed by #25154

  14. modified the milestones: urgent, 0.16.0 on Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavioroptimizationregressionIt worked in a previous version of Zig, but stopped working.

    Type

    No type

    Projects

    • Status
      Optimize Machine Code

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions