Skip to content

Fix slow compilation of large zero-initialized arrays; warn on large non-zero fills#586

Open
39ali wants to merge 1 commit into
Rust-GPU:mainfrom
39ali:array-memset
Open

Fix slow compilation of large zero-initialized arrays; warn on large non-zero fills#586
39ali wants to merge 1 commit into
Rust-GPU:mainfrom
39ali:array-memset

Conversation

@39ali

@39ali 39ali commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

let arr = [0; 32 * 1024] compiled very slowly. The cause: Rvalue::Repeat with a zero element routes through memset, while will create a huge list of repeated store instructions, the fix: use OpConstantNull instead when fill_byte == 0, valid for any SPIR-V composite type, single instruction regardless of size.

SPIR-V has no equivalent of OpConstantNull for non-zero values , so the best we can do is tell the user early by emitting a warning

@Firestar99 Firestar99 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix slow compilation

First, could you explain what kind of slowdown you're seeing?

use OpConstantNull instead when fill_byte == 0

I like that idea, although I'm unsure if spirt supports that command @eddyb?

will create a huge list of repeated store instructions

Isn't the bug then that the emitted OpConstantComposite was broken up into a bunch of individual OpStore instructions / not being reassembled into an OpCompositeConstruct / OpConstantComposite? (Our destructure_composites post-link pass may be related to this?)

@39ali

39ali commented Apr 24, 2026

Copy link
Copy Markdown
Contributor Author

i needed to clarify that for let arr = [0; 32 * 1024] it'll translate to OpConstantComposite
but for arr = [1; 32 * 1024] it'll translate to OpInBoundsAccessChain + OpStore

First, could you explain what kind of slowdown you're seeing?

compile time is slow, i believe its because of the long OpConstantComposite instruction

i'll attach the .spv file for this shader :

#![no_std]
use spirv_std::glam::Vec4;
use spirv_std::spirv;

#[inline(never)]
#[spirv(compute(threads(1)))]
pub fn self_assignment(
    #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [f32],
) {
    let arr = [0f32; 32 * 1024];
    for i in 0..arr.len() {
        y[i] = arr[i];
    }
} 

spirv.txt

}
SpirvType::Array { element, count } => {
if fill_byte == 0 {
return self.constant_null(ty.def(self.span(), self)).def(self);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Context (SPIR-T)

(Future) SPIR-T supports OpConstantNull (e.g. in Rust-GPU/spirt#45) so this is definitely a good catch and won't cause any issues!

I haven't implemented SPV_EXT_replicated_composites (and VK_EXT_shader_replicated_composites has pretty bad adoption - according to https://vulkan.gpuinfo.org/listextensions.php - not to mention we'd need user opt-in anyway).

However, SPIR-T could take OpConstantCompositeReplicateEXT as input, and specifically Rust-GPU/spirt#45 would map it to either undoing the optimization, or optionally re-emitting OpConstantCompositeReplicateEXT on the output side if the extension is enabled etc. (and internally SPIR-T could optimize for this situation, but it doesn't really depend on how SPIR-V does any of this).


What else you should/could do here:

  • because OpConstantNull supports all of these types, you can go as far as making memset_const_pattern return OpConstantNull regardless of the type, and not keeping it specific to arrays (and it would also support e.g. structs)
  • (optional) for full SpirvType::Adt support in memset_const_pattern you just need to iterate over field types
  • (optional) I'd almost want to say that constant_composite itself should check for this situation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants