C++ Logo

std-proposals

Advanced search

Re: [std-proposals] 回复: 回复: Proposal: Integer division/remainder/division-remainder functions with exception throwing behavior

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Wed, 30 Apr 2025 22:58:35 +0000
Here’s a benchmark.
Here are the results: using an AMD 7950X

MSVC on Windows:
func<div_ub> 324 ns 322 ns 2133333
func<div_check> 324 ns 328 ns 2240000
func<div_throw> 336 ns 338 ns 2036364
GCC on WSL:
func<div_ub> 324 ns 322 ns 2133333
func<div_check> 324 ns 328 ns 2240000
func<div_throw> 336 ns 338 ns 2036364

In other words. It makes almost no difference whatsoever, the exception one is slightly worse (but still not significant).
But hey, maybe my algorithm is bad, perhaps you can do better.
Ok that’s fine. Here’s a sample code, all you have to do is to come up with an implementation that improves those numbers.
But given that adding the check didn’t increase the time over the baseline in a way that you can even measure, I feel very comfortable to say that probably it is not worth it.



From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of None via Std-Proposals
Sent: Wednesday, April 30, 2025 7:50 PM
To: std-proposals_at_[hidden]
Cc: None <a1343922569_at_[hidden]>
Subject: [std-proposals] 回复: 回复: Proposal: Integer division/remainder/division-remainder functions with exception throwing behavior

I believe my point still stands for the following reasons (in my opinion):
1. Regarding branch prediction and performance:
Modern CPU pipelines are typically 14-20 stages deep. When a branch prediction fails, the entire pipeline needs to be flushed and refilled, causing a significant penalty of 20-30 clock cycles. This is particularly impactful in high-performance computing scenarios.
2. About implementation efficiency:
The proposed solution leverages CPU's native division-by-zero exception mechanism, which is fundamentally different from manual checking:
    No branch instructions in the main execution path.
    Zero runtime overhead for the non-zero case (>99.9% scenarios).
    Exception handling path is completely out of line.
    Modern CPUs have dedicated hardware for exception handling.
3. On "trivial implementation":
While users can implement basic checks, they cannot efficiently utilize CPU's built-in mechanisms without non-portable assembly code. A standardized solution would:
    Provide consistent, portable behavior.
    Enable compiler optimizations impossible with user-level code.

I believe these technical merits warrant consideration for standardization. Would you be interested in more detailed analysis of these aspects?

________________________________
From: Jan Schultke <janschultke_at_[hidden]<mailto:janschultke_at_[hidden]>>
Sent: Thursday, May 1, 2025 1:35 AM
To: std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Cc: None <a1343922569_at_[hidden]<mailto:a1343922569_at_[hidden]>>
Subject: Re: [std-proposals] 回复: Proposal: Integer division/remainder/division-remainder functions with exception throwing behavior

To clarify on the second point, you can already express a division by zero check with a throw on failure using an if statement. The language already has all the tools to let you do it.

If it was much faster to handle the CPU trap instead, compilers would likely already detect this pattern and transform the branch into an unconditional division. The core language already has all the tools, so this seems more like a quality-of-implementation problem than anything.

A much more interesting proposal would be to change division by zero globally so that it throws instead of being UB. Maybe this could be a conditionally supported feature. Maybe it's something that should be implemented in a compiler first. Maybe it's already implemented somewhere, not sure.


Received on 2025-04-30 22:58:40