Skip to content

Crate for choosing between 32-bit and 64-bit arithmetic backends #824

@tarcieri

Description

@tarcieri
Member

We have several crates that naively choose between a 32-bit or 64-bit implementation based on cfg(target_pointer_width).

However, in many cases, like ARMv7 and wasm32, LLVM can generate better code from the 64-bit implementation, even though the CPU is natively 32-bits.

Whatever heuristics are used, it's nice to be able to override the decision. Past experiences show crate features are a poor fit for this selection, however cfg attributes seem like a reasonable fit, as they leave the decision up to the toplevel [bin] crate.

The selection often needs to be cross-cutting across many crates. For example, the crypto-bigint and the https://github.com/rustcrypto/elliptic-curves crates built on top of it need to choose the same backend size.

To make that all work, I would propose having some utility crate for making this selection. An approach being used by curve25519-dalek is to have the selection made inside of a build script which sets defaults for cfg attributes if they aren't already set explicitly, which makes the actual cfg gating in the source code quite simple.

I think we could probably shoehorn such functionality into cpufeatures and use optional cfg attributes like cpufeatures_bits="32" or cpufeatures_bits="64" to make the selection. Or failing that, it could be put in a separate crate which is only intended to be used via build-dependencies.

Activity

newpavlov

newpavlov commented on Dec 29, 2022

@newpavlov
Member

I think it would make sense to define it first inside crypto-bigint and only if the functionality will be needed by another crate, move it into cpufeatures or a different crate.

In the case of elliptic curve crates, shouldn't they simply rely on crypto-bigint?

The only case I could think of where such functionality could be potentially useful is choosing between 32 and 64 bit software backends in polyval, but IIRC in its case it's more about availability of wide operations.

tarcieri

tarcieri commented on Dec 29, 2022

@tarcieri
MemberAuthor

@newpavlov polyval is another example yes.

Another example is the "soft" backends for the aes crate. It would be good when compiling to WASM to use the 64-bit backend

newpavlov

newpavlov commented on Dec 29, 2022

@newpavlov
Member

I am a bit hesitant to add such functionality to cpufeatures. As I see it, the crate is about runtime-by-default target feature detection, while arithmetic backend width will be completely determined by a bunch of cfgs. For example, it will be somewhat weird for crypto-bigint to pull libc on ARM Linux.

tarcieri

tarcieri commented on Dec 29, 2022

@tarcieri
MemberAuthor

Aah, that's true. Although we may want to do that anyway eventually to do gate the use of architecture-specific ASM, which would really help boost the speed.

But your point stands though... maybe it should go in a separate dependency-free crate specifically designed to be a build dependency only

added a commit that references this issue on Jan 8, 2023
added a commit that references this issue on Jan 8, 2023
tarcieri

tarcieri commented on Jan 8, 2023

@tarcieri
MemberAuthor

Started on a PR: #826

changed the title [-]Crate for choosing between 32-bit and 64-bit arithmetic backends (possibly `cpufeatures`)[/-] [+]Crate for choosing between 32-bit and 64-bit arithmetic backends[/+] on Jan 19, 2023
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @tarcieri@newpavlov

        Issue actions

          Crate for choosing between 32-bit and 64-bit arithmetic backends · Issue #824 · RustCrypto/utils