Rust: 정수 캐슀튞에 대한 부동 소수점윌로 읞핎 정의되지 않은 동작읎 발생할 수 있습니닀.

에 만든 2013년 10월 31음  Â·  234윔멘튞  Â·  출처: rust-lang/rust

2020-04-18 Ʞ쀀 상태

우늬는 as 대한 saturating-float-casts 동작을 안정화 할 계획읎며 읎전 동작을 처늬하는 안전하지 않은 띌읎람러늬 핚수륌 안정화했습니닀. 안정화 프로섞슀에 대한 최신 녌의는 # 71269륌 찞조하십시였.

2018-11-05 Ʞ쀀 상태

컎파음러에서 -Zsaturating-float-casts 플래귞가 구현되었습니닀.읎 플래귞는 몚든 float에서 정수 캐슀튞로 "포화"동작을 수행하여 겜계륌 ë²—ì–Žë‚œ 겜우 가장 가까욎 겜계로 고정됩니닀. 읎 변화에 대한 벀치마킹 요청 읎 얌마 전에 나왔습니닀. 결곌는 많은 프로젝튞에서 Ɥ정적읎지만 음부 프로젝튞 에서는 음을 나타냅니닀.

닀음 닚계는 읎러한 겜우에 성능을 복구하는 방법을 알아낎는 것입니닀.

  • 한 가지 옵션은 였늘의 as 캐슀튞 동작 (음부 겜우에는 UB)을 췚하고 ꎀ렚 유형 등에 대핮 unsafe 핚수륌 추가하는 것입니닀.
  • 또 닀륞 방법은 LLVM읎 freeze 개념을 추가 할 때까지 Ʞ닀늬는 것입니닀. 읎는 가비지 비튞 팚턎을 얻지 만 적얎도 UB가 아님을 의믞합니닀.
  • 또 닀륞 방법은 현재 윔드 생성읎 크게 최적화되지 않았Ʞ 때묞에 LLVM IR에서 읞띌읞 얎셈랔늬륌 통핎 캐슀튞륌 구현하는 것입니닀.

읎전 상태

업데읎튞 (@nikomatsakis 제공) : 많은 녌의 에 대한 계획의 Ʞ쎈륌 얻었


원래 묞제는 닀음곌 같습니닀.

값읎 ty2에 맞지 않윌멎 결곌가 정의되지 않습니닀.

1.04E+17 as u8
A-LLVM C-bug I-unsound 💥 P-medium T-lang

가장 유용한 댓Ꞁ

LLVM에서 float륌 int 캐슀튞로 포화시킀Ʞ위한 낎장 핚수륌 구현하Ʞ위한 작업을 시작했습니닀. https://reviews.llvm.org/D54749

귞것읎 얎디로 든 가멎 포화 의믞륌 얻는 비교적 낮은 였버 헀드 방법을 제공합니닀.

몚든 234 댓Ꞁ

지명

P-high에 대핮 허용됚, # 10183곌 동음한 추론

나는 읎것읎 ì–žì–Ž 수쀀에서 읎전 버전곌 혞환되지 않는닀고 생각하지 않습니닀. 정상적윌로 작동하던 윔드의 작동읎 쀑지되지는 않습니닀. 지명.

P-high로 변겜, # 10183곌 동음한 추론

읎 묞제와 # 10185륌 핎결하Ʞ 위핎 얎떻게 제안합니까? 동작읎 정의되는지 여부는 캐슀팅되는 숫자의 동적 값에 따띌 닀륎Ʞ 때묞에 유음한 핎결책은 동적 검사륌 삜입하는 것 같습니닀. 산술 였버플로에 대핮 귞렇게하고 싶지 않닀는 데 동의하는 것 같습니닀. 캐슀튞 였버플로에 대핮 수행핎도됩니까?

"안전한 변환"을 수행하는 LLVM에 낎장 핚수륌 추가 할 수 있습니닀. @zwarich 는 닀륞 아읎디얎가있을 수 있습니닀.

AFAIK는 현재 유음한 솔룚션은 타겟 별 낎장 핚수륌 사용하는 것입니닀. 적얎도 ë‚Žê°€ 묌얎 볞 사람에 따륎멎 JavaScriptCore 가하는 음입니닀.

였, 귞럌 충분히 쉜습니닀.

ping @pnkfelix 가 새로욎 였버플로 검사 항목윌로 덮여 있습니까?

읎러한 캐슀튞는 디버귞 ì–Žì„€ 션윌로 rustc에 의핎 확읞되지 않습니닀.

나는 읎것을 처늬하게되얎 Ʞ쁘지만 구첎적읞 핎결책읎 필요합니닀. 나는 개읞적윌로 맀우 유사한 묞제읎Ʞ 때묞에 였버플로 정수 산술곌 핚께 확읞핎알한닀고 생각합니닀. 나는 우늬가 묎엇을하는지 정말로 신겜 쓰지 않는닀.

읎 묞제는 현재 특정 상수 표현식에서 사용될 때 ICE륌 유발합니닀.

읎것은 닀음 포럌 게시묌의 예

Undefs, 응? Undefs는 재믞 있습니닀. 귞듀은 번식하는 겜향읎 있습니닀. 몇 분의 랭 Ꞁ링 후 ..

#[inline(never)]
pub fn f(ary: &[u8; 5]) -> &[u8] {
    let idx = 1e100f64 as usize;
    &ary[idx..]
}

fn main() {
    println!("{}", f(&[1; 5])[0xdeadbeef]);
}

-O륌 사용하여 낮 시슀템 (최신 알간)에서 segfaults.

안전한 녹의 메몚늬 안전성을 위반 한 I-unsound로 표시.

@bluss , 읎것은 나륌 위핎 segfualt가 아니띌 ë‹šì–ž 였류륌 제공합니닀. ë‚Žê°€ 추가 한 사람읎Ʞ 때묞에 태귞 í•Žì œ

한숚, 나는 -O, 닀시 태귞륌 잊었닀.

P-high에 대한 재 지명. 분명히 읎것은 얎느 시점에서 P-high 였지만 시간읎 지낚에 따띌 낮아졌습니닀. 읎것은 정확성을 위핎 맀우 쀑요핎 볎입니닀.

펞집 : 분류 죌석에 반응하지 않고 수동윌로 레읎랔을 추가했습니닀.

였버 플로우 (예 : 시프 팅)의 전례는 닚지 ì–Žë–€ 행동에 안죌하는 것 같습니닀. Java는 범위 몚듈로 결곌륌 생성하는 것 같습니닀. 읎는 불합늬하지 않은 것 같습니닀. 나는 우늬가 귞것을 처늬하는 데 필요한 LLVM 윔드의 종류륌 잘 몚륎겠습니닀.

https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls -5.1.3에 따륎멎 Java는 NaN 값읎 0 및 묎한대로 맀핑되도록 볎장합니닀. 표현 가능한 최소 / 최대 정수로. 또한 변환을위한 Java 규칙은 닚순히 래핑하는 것볎닀 더 복잡합니닀. 포화 ( int 또는 long 로의 변환)와 래핑 (더 작은 정수 유형윌로의 변환)의 조합 음 수 있습니닀. , 필요한 겜우). Java에서 전첎 변환 알고늬슘을 복제하는 것은 확싀히 가능하지만 몚든 캐슀튞에 대핮 상당한 양의 작업읎 필요합니닀. 특히 LLVM에서 fpto[us]i 작업의 결곌가 정의되지 않은 동작을 나타낎지 않도록하렀멎 범위 검사가 필요합니닀.

대안윌로 float-> int 캐슀튞는 원래 값의 잘늌읎 대상 유형의 값 (또는 [iu]size ?)윌로 표현 될 수있는 겜우에만 유횚하닀고 볎장하고 값읎 충싀하게 표현되지 않았을 때 팚닉을 유발하는 디버귞 빌드에 대한 죌장읎 있습니닀.

Java ì ‘ê·Œ 방식의 죌요 장점은 변환 Ʞ능읎 전첎적읎띌는 것입니닀. 귞러나 읎는 예Ʞ치 않은 동작읎 발생할 수 있닀는 것을 의믞합니닀. 정의되지 않은 동작을 방지 할 수 있지만 캐슀튞가 싀제로 의믞가 있는지 확읞하지 않도록 속읎Ʞ 쉜습니닀. (읎것은 불행히도 닀륞 캐슀튞에도 핎당됩니닀 : worried :).

닀륞 ì ‘ê·Œ 방식은 현재 산술 연산에 사용되는 ì ‘ê·Œ 방식곌 음치합니닀. 늎늬슀의 간닚하고 횚윚적읞 구현, 디버귞의 범위 검사에 의핎 튞늬거되는 팹닉. 안타깝게도 닀륞 as 캐슀튞와는 달늬 읎러한 변환읎 확읞되얎 사용자에게는 놀띌욎 음읎 될 수 있습니닀 (아마도 여Ʞ서 산술 연산에 대한 비유가 도움읎 될 수 있음). 읎것은 또한 음부 윔드륌 손상시킬 수 있지만 AFAICT는 현재 정의되지 않은 동작에 의졎하는 윔드에서만 발생핎알합니닀 (슉, 정의되지 않은 동작 "정수륌 반환하자, 당연히 얎느 것읎 든 상ꎀ하지 않습니닀"륌 팚닉윌로 대첎합니닀).

묞제는 "정수륌 반환하자, 당신은 분명히 얎느 것을 신겜 쓰지 않는닀"가 아니띌, 귞것은 임의의 값읎 아닌 비강 악마 값읞 undef륌 유발하고 LLVM은 undef가 발생하지 않는닀고 가정 할 수 있닀는 것입니닀. 끔찍한 잘못된 작업을 수행하는 최적화륌 가능하게합니닀. 묎작위 값읎지만 결정적윌로 undef가 아니띌멎 걎전성 묞제륌 핎결하Ʞ에 충분할 것입니닀. 표현할 수없는 값읎 얎떻게 표현되는지 정의 할 필요가 없습니닀. undef륌 막Ʞ 만하멎됩니닀.

@ rust-lang / compiler 회의에서 녌의되었습니닀. 가장 음ꎀ된 조치는 닀음곌 같습니닀.

  1. 였버플로 확읞읎 활성화되멎 잘못된 캐슀튞 및 팚닉을 확읞합니닀.
  2. 귞렇지 않윌멎 폎백 동작읎 필요합니닀. 유횚한 값에 대핮 최소한의 (읎상적윌로는 0) 런타임 비용읎 있얎알하지만 LLVM undef가 아닌 한 정확한 동작은 귞닀지 쀑요하지 않습니닀.

죌요 묞제는 옵션 2에 대한 구첎적읞 제안읎 필요하닀는 것입니닀.

분류 : P- 쀑간

@nikomatsakis as 가) 현재 디버귞 빌드에서 팹닉 상태가됩니까? 귞렇지 않은 겜우 음ꎀ성곌 예잡 가능성을 위핎 귞대로 유지하는 것읎 좋습니닀. (나는 귞것읎 산술곌 마찬가지로 _핎알한닀고 생각하지만, 귞것은 별개의 곌거의 녌쟁입니닀.)

귞렇지 않윌멎 폎백 동작읎 필요합니닀. 유횚한 값에 대핮 최소한의 (읎상적윌로는 0) 런타임 비용읎 있얎알하지만 LLVM undef가 아닌 한 정확한 동작은 귞닀지 쀑요하지 않습니닀.

구첎적읞 제안 : 숫자와 지수륌 u64 로 추출하고 지수로 비튞 시프튞 숫자륌 추출합니닀.

fn f64_as_u64(f: f64) -> u64 {
    let (mantissa, exponent, _sign) = f.integer_decode();
    mantissa >> ((-exponent) & 63)
}

예, 비용읎 0은 아니지만 닀소 최적화 가능하며 ( integer_decode inline 표시하멎 더 좋을 것입니닀) 적얎도 결정적입니닀. float-> int 캐슀튞륌 확장하는 믞래의 MIR-pass는 아마도 float가읎 묎거욎 변환을 캐슀튞하고 걎너 뛾 수 있는지 여부륌 분석 할 수 있습니닀.

LLVM에는 변환 Ʞ능에 대한 플랫폌 낎장 핚수가 없습니까?

펞집 : @zwarich 는 말했닀 (였래 전) :

AFAIK는 현재 유음한 솔룚션은 타겟 별 낎장 핚수륌 사용하는 것입니닀. 적얎도 ë‚Žê°€ 묌얎 볞 사람에 따륎멎 JavaScriptCore 가하는 음입니닀.

왜 당황 하는가? AFAIK, @glaebhoerl 읎 정확하고, as 는 자륎Ʞ / 확장핎알하며, 플연산자륌 확읞하지 _ 않습니닀.

2016 년 3 월 5 음 토요음 03:47:55 AM -0800, Gábor Lehel은 닀음곌 같읎 썌습니닀.

@nikomatsakis as 가) 현재 디버귞 빌드에서 팹닉 상태가됩니까? 귞렇지 않은 겜우 음ꎀ성곌 예잡 가능성을 위핎 귞대로 유지하는 것읎 좋습니닀. (나는 귞것읎 산술곌 마찬가지로 _핎알한닀고 생각하지만, 귞것은 별개의 곌거의 녌쟁입니닀.)

진싀. 섀득력읎 있습니닀.

2016 년 3 월 9 음 수요음 02:31:05 AM -0800에 Eduard-Mihai Burtescu는 닀음곌 같읎 썌습니닀.

LLVM에는 변환 Ʞ능에 대한 플랫폌 낎장 핚수가 없습니까?

수정 :

AFAIK는 현재 유음한 솔룚션은 타겟 별 낎장 핚수륌 사용하는 것입니닀. 적얎도 ë‚Žê°€ 묌얎 볞 사람에 따륎멎 JavaScriptCore 가하는 음입니닀.

왜 당황 하는가? AFAIK, @glaebhoerl 읎 정확하고, as 는 자륎Ʞ / 확장핎알하며, 플연산자륌 확읞하지 _ 않습니닀.

ë„€, 전에 착각 한 것 같아요. as 는 "선택되지 않은 잘늌"입니닀.
더 좋든 나쁘 든, 음ꎀ성을 유지하는 것읎 가장 좋습니닀.
ê·ž 철학윌로. 타겟 별 낎장 핚수륌 사용하멎 완벜하게
귞래도 좋은 í•Žê²°ì±…?

@nikomatsakis : 동작읎 아직 정의되지 않은 것 같습니닀. 귞것에 ꎀ한 계획에 대한 업데읎튞륌 쀄 수 있습니까?

훚씬 적은 숫자로읎 묞제륌 만났습니닀.

    let x: f64 = -1.0;
    x as u8

최적화에 따띌 0, 16 등의 결곌가 나였며, 255로 정의되Ʞ륌 바랐윌므로 x as i16 as u8 륌 ì“ž 필요가 없습니닀.

@gmorenz !0u8 핎볎 셚나요?

말읎 안되는 상황에서 저는 넀튞워크륌 통핎 전송 된 데읎터에 대한 변환에서 f64륌 [-255, 255] 범위로 얻었습니닀. 나는 귞것읎 멋지게 포장되Ʞ륌 바랬닀 ( <i32> as u8 포장하는 것곌 똑같은 방식윌로).

여Ʞ에 "kill undef" http://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html에 대한 최귌 LLVM 제안읎 있습니닀. 읎 묞제.

귞듀은 undef륌 포읎슌윌로 대첎하고 있윌며, 의믞는 앜간 닀늅니닀. int-> float 캐슀튞 정의 된 동작을 만듀지는 않을 것입니닀.

우늬는 아마 포화 캐슀튞륌 할 수있는 몇 가지 명시적읞 방법을 제공핎알합니까? 나는 지ꞈ 바로 ê·ž 정확한 행동을 원했습니닀.

https://github.com/rust-lang/rust/issues/10184#issuecomment -139858153읎 죌얎지멎 I-crash로 표시되얎알합니닀.

였늘 #rust-beginners 에서 읎것에 대한 질묞읎있었습니닀. 누군가가 알생에서읎 묞제륌 만났습니닀.

@jimblandy , _Programming Rust_와 핚께 쓰고있는 책은읎 버귞륌 얞꞉합니닀.

여러 종류의 캐슀튞가 허용됩니닀.

  • 숫자는 Ʞ볞 제공 숫자 유형에서 닀륞 유형윌로 캐슀튞 될 수 있습니닀.

    (...)

    귞러나읎 Ꞁ을 쓰는 시점에서 큰 부동 소수점 값을 너묎 작아서 나타낌 수없는 정수 유형윌로 캐슀팅하멎 정의되지 않은 동작읎 발생할 수 있습니닀. 읎것은 안전한 Rust에서도 충돌을 음윌킬 수 있습니닀. 컎파음러 github.com/rust-lang/rust/issues/10184 의 버귞입니닀.

읎 장의 마감음은 5 월 19 음입니닀. 마지막 닚띜을 삭제하고 싶지만, 적얎도 여Ʞ에서 뚌저 ì–Žë–€ 종류의 계획읎 있얎알한닀고 생각합니닀.

분명히 현재 JavaScriptCore는 x86 사용합니닀 . 귞듀은 CVTTSD2SI 명령얎륌 사용하고 값읎 범위륌 벗얎나멎 턞읎 많은 C ++로 돌아갑니닀. 현재 범위륌 ë²—ì–Žë‚œ 값읎 폭발하Ʞ 때묞에 핎당 명령얎륌 사용하멎 (대첎없읎!) 현재 우늬가 가진 것볎닀 개선 될 수 있지만 하나의 아킀텍처에서만 가능합니닀.

솔직히 저는 as 숫자 형 캐슀튞륌 사용하지 않고 From 및 TryFrom 또는 conv crate와 같은 것을 사용핎알한닀고 생각합니닀.

아마도 귞럎 수도 있지만 귞것은 나에게 직각 읞 것 같습니닀.

좋아요,읎 몚든 대화륌 닀시 읜었습니닀. 읎 작업읎 당황핎서는 안된닀는 동의가 있닀고 생각합니닀 ( as 와의 음반적읞 음ꎀ성을 위핎). 행동읎 얎떻게되얎알하는지에 대한 두 가지 죌요 겜쟁자가 있습니닀.

  • 음종의 정의 된 결곌
  • 정의되지 않은 값 (정의되지 않은 동작 아님)

    • 장점 :읎륌 통핎 각 플랫폌에서 사용할 수있는 플랫폌 별 낎장 핚수 만 사용할 수 있습니닀.

    • 닚점 : 휮대 성 위험입니닀. 음반적윌로 최소한 ì–žì–Žë¡œ 는 정의되지 않은 결곌륌 자죌 사용하지 않은 것 같습니닀 (여러 곳의 libs에서 수행한닀고 확신합니닀).

첫 번짞 겜우에 ì–Žë–€ 결곌 가되얎알 하는지에 대한 명확한 선례가 있는지 확싀하지 않습니닀.

귞것을 작성한 후 결정 론적 결곌륌 유지하는 것읎 선혞됩니닀. 나는 우늬가 결정론에 대한 겜계륌 유지할 수있는 몚든 곳읎 승늬띌고 느낍니닀. 귞래도 결곌가 뭔지 잘 몚륎겠습니닀.

나는 귞것을 읎핎할 수 있고 유용 핮 볎읎Ʞ 때묞에 채도륌 좋아하지만, u64 as u32 읎 잘늬는 방식곌는 얎딘지 몚순되는 것 같습니닀. 귞래서 아마도 잘늌을 Ʞ반윌로 한 ì–Žë–€ 종류의 결곌가 의믞가 있을 것 입니닀.

낮 윔드는 0..2 ^ 64 범위의 항목에 대핮 올바륞 값을 제공하고 닀륞 몚든 항목에 대핎서는 결정적읎지만 가짜 값을 제공합니닀.

부동 소수점은 가수 ​​^ 지수로 표시됩니닀. 예륌 듀얎 1.0 는 (2 << 52) ^ -52 읎고 비튞 시프튞와 지수는 읎진법에서 동음하므로 시프튞륌 반전 할 수 있습니닀 (따띌서 지수와 였륞쪜의 부정 시프튞).

결정론의 겜우 +1.

나는 읞간에게 좋은 의믞륌 두 가지볎고 , 컎파음러가 계산을 최적화 할 수 없을 때 범위 낎에있는 값에 대핮 더 빠륞 의믞륌 선택핎알한닀고 생각합니닀. (컎파음러가 값읎 범위 낎에 있음을 알게되멎 두 옵션 몚두 동음한 결곌륌 제공하므로 똑같읎 최적화 할 수 있습니닀.)

  • 채도 (범위륌 ë²—ì–Žë‚œ 값은 IntType::max_value() / min_value() )
  • 몚듈로 (범위륌 ë²—ì–Žë‚œ 값은 뚌저 bigint로 변환 한 닀음 잘띌낎는 것처럌 처늬됚)

아래 표는 두 옵션을 몚두 지정하Ʞ위한 것입니닀. T 는 몚든 ëšžì‹  정수 유형입니닀. Tmin 및 Tmax는 T::min_value() 및 T::max_value() 입니닀. RTZ (v)는 v의 수학적 값을 췚하고 수학적 정수륌 얻Ʞ 위핎 0윌로 반올늌 핚을 의믞합니닀.

v | v as T (채도) | v as T (몚듈로)
---- | ---- | ----
범위 낮 (Tmin <= v <= Tmax) | RTZ (v) | RTZ (v)
마읎너슀 제로 | 0 | 0
NaN | 0 | 0
묎한대 | Tmax | 0
-묎한 | Tmin | 0
v> Tmax | Tmax | T에 맞게 잘늰 RTZ (v)
v <Tmin | Tmin | T에 맞게 잘늰 RTZ (v)

ECMAScript 표쀀은 작업 ToInt32 , ToUint32, ToInt16, ToUint16, ToInt8, ToUint8을 지정하고 위의 "몚듈로"옵션을 사용하는 낮 의도는 몚든 겜우에 핎당 작업을 음치시킀는 것입니닀.

ECMAScript는 또한 위의 두 겜우와 음치하지 않는 ToInt8Clamp 륌 지정합니닀. "0윌로 반올늌"읎 아닌 소수 값에 대핮 "반올늌에서 짝수"로 반올늌합니닀.

@ oli-obk의 제안은 범위 낎에있는 값에 대핮 계산하는 것읎 더 빠륞지 고렀할 가치가있는 ì„ž 번짞 방법입니닀.

@ oli-obk 부혞있는 정수 유형은 얎떻습니까?

닀륞 제안을 혌합에 던지Ʞ : Mark u128은 안전하지 않은 플로튞에 캐슀팅하고 사람듀읎읎륌 처늬하는 방법을 명시 적윌로 선택하도록합니닀. u128은 현재 맀우 드뭅니닀.

@Manishearth 비슷한 의믞의 정수 → 부동 소수점 → 정수륌 원합니닀. 둘 ë‹€ UB-ful읎고 더 읎상 float → integer륌 안전하지 않게 만듀 수 없윌므로 integer → float륌 안전하지 않게 만드는 것도 플핎알합니닀.

float → integer saturating의 겜우 AFAICT가 더 빚띌집니닀 (결곌적윌로 and , test + jump float 비교 및 ​​점프, 몚두 현대 아치에서 0.66 또는 0.5 2-3 사읎큎). 나는 개읞적윌로 범위 낮 값읎 가능한 한 빠륞 한 우늬가 결정한 정확한 행동에 대핮 덜 신겜을 ì“ž 수 없습니닀.

였버플로처럌 행동하는 것읎 말읎되지 않습니까? 따띌서 디버귞 빌드에서 정의되지 않은 동작윌로 캐슀튞륌 수행하멎 팚닉읎 발생합니닀. 귞런 닀음 1.04E+17.saturating_cast::<u8>() , unsafe { 1.04E+17.unsafe_cast::<u8>() } 및 잠재적윌로 닀륞 것곌 같은 캐슀팅 동작을 지정하는 메서드륌 가질 수 있습니닀.

였, 나는 묞제가 u128에만 핎당한닀고 생각했고 두 가지 방법윌로 안전하지 않게 만듀 수 있습니닀.

@cryze UB는 안전 윔드의 늎늬슀 몚드에서도 졎재하지 않아알합니닀. 였버플로 항목은 여전히 ​​정의 된 동작입니닀.

슉, 디버귞시 팚닉읎 발생하고출시되멎 좋을 것입니닀.

읎것은 닀음에 영향을 믞칩니닀.

  • f32 -> u8, u16, u32, u64, u128, usize (몚두 -1f32 as _ , u128을 제왞한 몚두 f32::MAX as _ )
  • f32 -> i8, i16, i32, i64, i128, isize (몚두 f32::MAX as _ )
  • f64 -> 몚든 정수 (몚두 f64::MAX as _ )

f32::INFINITY as u128 도 UB입니닀.

@CryZe

였버플로처럌 행동하는 것읎 말읎되지 않습니까? 따띌서 디버귞 빌드에서 정의되지 않은 동작윌로 캐슀튞륌 수행하멎 팚닉읎 발생합니닀.

읎것은 ë‚Žê°€ 처음에 생각,하지만 난 것을 상Ʞ 된 것입니닀 as (우늬는 핚께 확읞 였버 플로우하지 않는 변환읎 현재 당황하지 as 좋든 나쁘 든). 따띌서 가장 유사한 것은 "정의 된 작업을 수행"하는 것입니닀.

FWIW, "kill undef"는 싀제로 메몚늬의 안전하지 않은 묞제륌 핎결하는 방법을 제공하지만 결곌는 비 결정적입니닀. 죌요 구성 요소 쀑 하나는 닀음곌 같습니닀.

3) 전파륌 쀑지하는 새 명령얎 '% y = freeze % x'륌 만듭니닀.
독. 입력읎 독읎멎 임의의 값을 반환하지만 고정되얎 있습니닀.
값. (였래된 undef와 같지만 각 사용은 동음한 값을 얻습니닀), 귞렇지 않윌멎
입력 값을 반환합니닀.

였늘날 undefs가 메몚늬 안전성을 위반하는 데 사용될 수있는 읎유는 사용 사읎, 특히 겜계 검사와 후속 포읞터 산술 사읎에서 마술처럌 값을 변겜할 수 있Ʞ 때묞입니닀. rustc읎 몚든 위험한 캐슀튞 후에 동결을 추가했닀멎, 당신은 알 수 없지만 잘 작동하는 값을 얻게 될 것입니닀. 성능 잡멎에서 freeze는 Ʞ볞적윌로 묎료입니닀. 묌론 캐슀튞에 핎당하는 Ʞ계 명령은 변동하는 값읎 아닌 닚음 값을 생성하Ʞ 때묞입니닀. 옵티마읎 저가 ì–Žë–€ 읎유로 캐슀튞 명령얎륌 복제하는 것처럌 느껎지더띌도 범위륌 ë²—ì–Žë‚œ 입력에 대한 결곌는 음반적윌로 죌얎진 아킀텍처에서 결정적읎Ʞ 때묞에 귞렇게하는 것읎 안전핎알합니닀.

...하지만 궁ꞈ한 점읎 있닀멎 아킀텍처 전반에 걞쳐 결정적읎지는 않습니닀. x86은 몚든 잘못된 입력에 대핮 0x80000000을 반환합니닀. ARM은 범위륌 ë²—ì–Žë‚œ 입력에 대핮 포화 상태읎며 (읎 의사 윔드륌 였륞쪜윌로 읜는 겜우) NaN에 대핮 0을 반환합니닀. 따띌서 목표가 결정적읎고 플랫폌 독늜적 읞 결곌 륌 생성하는 것읎띌멎 플랫폌의 fp-to-int 낎장 핚수륌 사용하는 것만윌로는 충분하지 않습니닀. 적얎도 ARM에서는 예왞에 대한 상태 레지슀터도 확읞핎알합니닀. 읎것은 ê·ž 자첎로 앜간의 였버 헀드륌 가질 수 있윌며, intrinsic을 아직 사용하지 않은 드묞 겜우에 자동 벡터화륌 확싀히 방지합니닀. 또는 정규 비교 작업을 사용하여 범위 낮 값을 명시 적윌로 테슀튞 한 닀음 정규 float-to-int륌 사용할 수 있습니닀. 옵티 마읎저에서 훚씬 더 좋게 듀늜니닀 

as 전환은 현재 당황하지 않습니닀.

ì–Žë–€ 시점에서 우늬는 + 을 팹닉 (디버귞 몚드에서)윌로 변겜했습니닀. 읎전에 UB였던 쌀읎슀에서 as 팚닉을 볞닀고핎서 놀띌지 않을 것입니닀.

우늬가 (우늬가핎알하는) 확읞에 ꎀ심읎 있닀멎, 우늬는 as (유음한 옵션 읞 유슀 쌀읎슀가 있습니까?)륌 사용하지 않거나 최소한 사용하지 말띌고 조얞하고 사람듀을 닀음곌 같은 것윌로 읎동시쌜알합니닀. TryFrom 및 TryInto 대신 as 을 (륌) 귞대로두Ʞ로 결정했을 때 되돌멮 계획 읎띌고 말한 것입니닀. 나는 녌의쀑읞 사례 가 추상 에서 as 가 ì–Žë–€ 검사도하지 않도록 읎믞 정의 된 사례 와 질적윌로 닀륎지 않닀고 생각합니닀. 찚읎점은 싀제로 읎러한 겜우에 대한 구현읎 현재 불완전하고 UB가 있닀는 것입니닀. 당신읎 의지 할 수없는 섞계 as 검사륌하고 (대부분의 유형을 위핎, 귞것은하지 ì•Šêž° 때묞에), 당신은 당황하지에 의졎 할 수없는 (때묞에 ì–Žë–€ 종류의, 귞것은 것), 귞늬고 귞것은 음치하지, 귞늬고 우늬는 여전히 나에게 ê·žë“€ 몚두의 가장 나쁜 것 같닀되지 않았닀.

귞래서읎 시점에서 @jorendorff는 Ʞ볞적윌로 나에게 가장 좋은 계획 읞 것처럌 볎읎는 것을 엎거했닀고 생각합니닀.

  • as 에는 결정 론적 동작읎 있습니닀.
  • 얌마나 합늬적읞지, 얌마나 횚윚적읞지의 조합에 따띌 행동을 선택합니닀.

귞는 ì„ž 가지 가능성을 엎거했습니닀. 낚은 작업은 읎러한 가능성을 조사하거나 적얎도 귞쀑 하나 륌 조사하는 것읎띌고 생각합니닀. 슉, 싀제로 구현하고 "느늌"또는 "빠늄"에 대한 느낌을 얻윌십시였.

거Ʞ에 찌륎렀는 동Ʞ륌 느끌는 사람읎 있습니까? 누군가륌 끌얎 듀읎Ʞ 위핎 읎것을 E-help-wanted 로 태귞하겠습니닀. (@ oli-obk?)

ì–Ž, 나는 크로슀 플랫폌 음ꎀ성에 대한 대가륌 치륎고 싶지 않습니닀 : / 귞것은 가비지 읞, 쓰레Ʞ가 나가는 것에 ꎀ심읎 없습니닀 (귞러나 디버귞 죌장읎 맀우 도움읎 될 것입니닀).

현재 Rust의 몚든 반올늌 / 자륎Ʞ 핚수는 맀우 느늜니닀 (정확하게 구현 된 핚수 혞출). 따띌서 as 는 빠륞 부동 반올늌을위한 마지막 수닚입니닀.

as ë² ì–Ž cvttss2si 읎왞의 것을 만듀렀고한닀멎, ê·ž 자첎로 안정적읞 대안도 추가하십시였.

@pornel 읎것은 읎론적 읞 종류의 UB가 아니띌 귞것읎 ub임을 묎시하멎 ꎜ찮은 것읎 아니띌 싀제 섞계에 영향을 믞칩니닀. 싀제 윔드 예제에서 # 41799륌 추출했습니닀.

@ est31 UB로 낚겚 두는 것읎 잘못되었닀는 데 동의하지만 UB에 대한 핎결책윌로 freeze 제안 된 것을 볎았습니닀. 정의 된 결정 론적 값을 만드는 AFAIK, 당신은 닚지 얎느 것을 말할 수 없습니닀. ê·ž 행동은 ꎜ찮습니닀.

난 ꎜ찮을거알 귞래서 예륌 듀멎 겜우 u128::MAX as f32 결정 론적윌로 생산 17.5 86에, 및 999.0 - 64에, 및 -555 ARM합니닀.

freeze 는 정의되고 결정적읎며 지정되지 않은 값을 생성하지 않습니닀. ê·ž 결곌는 여전히 "컎파음러가 좋아하는 몚든 비튞 팹턮"읎며 동음한 작업을 사용하는 겜우에만 음ꎀ됩니닀. 읎것은 사람듀읎 위에서 수집 한 UB 생성 예제륌 회플 할 수 있지만 닀음을 제공하지는 않습니닀.

u128 :: MAX as f32는 결정적윌로 x86에서 17.5, x86-64에서 999.0, ARM에서 -555륌 생성했습니닀.

예륌 듀얎, LLVM읎 u128::MAX as f32 였버플로륌 감지하고읎륌 freeze poison 대첎하는 겜우 x86_64에서 fn foo() -> f32 { u128::MAX as f32 } 의 유횚한 하강은 닀음곌 같습니닀.

foo:
  ret

(슉, 반환 레지슀터에 마지막윌로 저장된 것을 반환합니닀)

ë‚Žê°€ ì°žì¡°. 귞것은 여전히 ​​낮 용도로 허용됩니닀 (범위륌 ë²—ì–Žë‚œ 값읎 예상되는 겜우 믞늬 큎랚핑합니닀. 범위 낮 값을 Ʞ대하지만 귞렇지 않은 겜우 ì–Žë–€ 겜우에도 올바륞 결곌륌 얻지 못할 것입니닀) .

값읎 고정되얎있는 한 임의의 값을 반환하는 범위륌 ë²—ì–Žë‚œ 플로튞 캐슀튞에 묞제가 없윌므로 더 읎상 정의되지 않은 동작을 음윌킬 수 없습니닀.

LLVM에서 freeze 같은 것을 사용할 수 있습니까? 나는 귞것읎 순전히 읎론적 읞 구성읎띌고 생각했습니닀.

@nikomatsakis 나는 귞것읎 ( poison 와는 달늬) 귞렇게 사용되는 것을 볞 적읎 없습니닀.

freeze 는 였늘날 LLVM에 전혀 졎재하지 않습니닀. 제안 된 것음뿐입니닀 (

여Ʞ에 제안 된 변겜 사항에 대핎볎닀 ꎑ범위한 녌의륌 위핎 RFC륌 ì—Žê³  싶습니까? IMO, as 의 성능에 잠재적윌로 영향을 믞치는 몚든 것은 녌쟁의 여지가있을 것읎지만, 사람듀에게 귞듀의 목소늬륌듀을 Ʞ회륌죌지 않는닀멎 두 배의 녌쟁읎 될 것입니닀.

저는 Julia 개발자읎며 동음한 LLVM 백엔드륌 공유하고 유사한 묞제가 있Ʞ 때묞에읎 묞제륌 한동안 지쌜 왔습니닀. ꎀ심읎있는 겜우 닀음곌 같읎 결정했습니닀 (낮 컎퓚터의 닚음 Ʞ능에 대한 대략적읞 타읎밍 포핚).

  • unsafe_trunc(Int64, x) 는 핎당 LLVM 낎장 fptosi (1.5ns)에 직접 맀핑됩니닀.
  • trunc(Int64, x) 는 범위륌 ë²—ì–Žë‚œ 값 (3ns)에 대한 예왞륌 발생시킵니닀.
  • convert(Int64, x) 는 범위륌 ë²—ì–Ž 났거나 정수가 아닌 값 (6ns)에 대핮 예왞륌 발생시킵니닀.

또한 정의되지 않은 동작을 좀 더 정의 하도록 메음 링늬슀튞 에

@bstrie RFC는 ꎜ찮지 만 데읎터가 있윌멎 확싀히 유용하닀고 생각합니닀! 귞러나 @simonbyrne 의 의견은 ê·ž 점에서 맀우 유용합니닀.

나는 JS 의믞론 ( @jorendorff 몚듈로 얞꞉)곌 "포화"ì—Žë¡œ 볎읎는 자바 의믞론 을 가지고 놀았닀. 핎당 링크가 만료되는 겜우 JS 및 Java 입니닀.

나는 또한 (?)가 맞닀고 생각하는 Rust에서 포화 의 벀치 마크 수치 도 얻었습니닀. 흥믞롭게도 포화 구현읎 낎장 핚수볎닀 2-3 ë°° 느늬닀는 것을 알고 있습니닀. @simonbyrne읎 2 ë°° 더 느늬게 발견 한 것곌

Rust에서 "mod"의믞론을 구현하는 방법을 완전히 몚륎겠습니닀 ...

하지만 저에게는 성능읎 필요한 사람듀을 위핎 수많은 f32::as_u32_unchecked() 메서드가 필요하닀는 것읎 분명핎 볎입니닀.

성능읎 필요한 사람듀을 위핎 많은 f32::as_u32_unchecked() 메서드가 필요하닀는 것읎 분명핎 볎입니닀.

귞것은 안타까욎 음입니닀. 아니멎 안전하지만 구현 정의 된 변형을 의믞합니까?

구현 정의 빠륞 Ʞ볞값에 대한 옵션읎 없습니까?

@eddyb 나는 우늬가 가지고 거띌고 생각했닀 unsafe fn as_u32_unchecked(self) -> u32 에 f32 묎엇에 직접 아날로귞 읞 및 as 였늘입니닀.

필자가 작성한 Rust 구현읎 최적읎띌고 죌장하지는 않겠지 만,읎 슀레드륌 읜을 때 대부분의 시간 동안읎 슀레드 결정론곌 안전성읎 속도볎닀 더 쀑요하닀는 읞상을 받았습니닀. unsafe 탈출 핎치는 욞타늬 반대펞에있는 사람듀을위한 것입니닀.

귞렇닀멎 저렎한 플랫폌 의졎적 변형읎 없습니까? 나는 빚늬 묎얞가가 지정되지 않은 값을 제공 할 때 겜계의 왞부 안전합니닀. 나는 음부 입력에 UB륌 원하지 않윌며 우늬가 더 잘 할 수 있닀멎 음반적읞 사용에는 너묎 위험하닀고 생각합니닀.

ë‚Žê°€ 아는 한, 대부분의 플랫폌에서읎 변환을 구현하는 표쀀 방법은 UB가 아닌 범위륌 ë²—ì–Žë‚œ 입력에 대핮 묎얞가 륌 수행합니닀. 귞러나 LLVM은 UB륌 통핎 핎당 옵션을 선택할 수있는 방법읎없는 것 같습니닀. LLVM 개발자가 범위륌 ë²—ì–Žë‚œ 입력에 대핮 "지정되지 않았지만 undef / poison "결곌가 아닌 낎장 핚수륌 도입하도록 섀득 할 수 있닀멎읎륌 사용할 수 있습니닀.

하지만읎 슀레드의 누군가가 섀득력있는 RFC (llvm-dev 목록에 있음)륌 작성하고 동의륌 얻얎 구현핎알 할 것윌로 예상합니닀 (백엔드에서 우늬가 신겜 쓰는 백엔드에서 닀륞 목표). 아마도 llvm-dev가 êž°ì¡Ž 캐슀튞륌 UB가 아닌 것윌로 만듀도록 섀득하는 것볎닀 쉬욞 것입니닀 ( "C 및 C ++ 프로귞랚을 느늬게 만듀 것"곌 같은 질묞을 회플하Ʞ 때묞입니닀). 귞러나 여전히 쉜지는 않습니닀.

닀음 쀑에서 선택하는 겜우륌 대비하여 :

채도 (범위륌 ë²—ì–Žë‚œ 값은 IntType :: max_value () / min_value ()가 됚)
몚듈로 (범위륌 ë²—ì–Žë‚œ 값은 뚌저 bigint로 변환 한 닀음 잘띌낎는 것처럌 처늬됚)

값읎 컀짐에 따띌 부동 소수점의 절대 정밀도가 빠륎게 떚얎지Ʞ 때묞에 IMO 전용 채도는 여Ʞ서 의믞가 있습니닀. 따띌서 얎느 시점에서 몚듈로는 몚두 0처럌 쓞몚없는 것읎 될 것입니닀.

I는읎 표시 E-needs-mentor 하고 귞것을 태귞 WG-compiler-middle 가 IMPL Ʞ간읎 추가로 조사 할 수있는 좋은 시간읎 될 수도 볎읎Ʞ 때묞에! Ʞ록 계획에 대한 나의 êž°ì¡Ž

ë¿¡ 빵뀚

IIRC LLVM은 ê²°êµ­ freeze 구현할 계획입니닀. 귞러멎 freeze 륌 수행하여 UB륌 처늬 할 수 ​​있습니닀.

낮 결곌 : https://gist.github.com/s3bk/4bdfbe2acca30fcf587006ebb4811744

_array 변형은 1024 개 값의 룚프륌 싀행합니닀.
_ 캐슀튞 : x as i32
_clip : x.min (MAX) .max (MIN) as i32
_panic : x가 범위륌 벗얎나멎 팹닉
_zero : 범위륌 ë²—ì–Žë‚œ 겜우 결곌륌 0윌로 섀정합니닀.

test bench_array_cast       ... bench:       1,840 ns/iter (+/- 37)
test bench_array_cast_clip  ... bench:       2,657 ns/iter (+/- 13)
test bench_array_cast_panic ... bench:       2,397 ns/iter (+/- 20)
test bench_array_cast_zero  ... bench:       2,671 ns/iter (+/- 19)
test bench_cast             ... bench:           2 ns/iter (+/- 0)
test bench_cast_clip        ... bench:           2 ns/iter (+/- 0)
test bench_cast_panic       ... bench:           2 ns/iter (+/- 0)
test bench_cast_zero        ... bench:           2 ns/iter (+/- 0)

개별 작업에 대핮 결곌륌 정수로 반올늌 할 필요가 없습니닀. 분명히읎 2ns / iter 뒀에는 앜간의 찚읎가있을 것입니닀. 아니멎 4 개 변형 몚두에 대핮 _ 정확히 _ 2ns와 같은가요?

@ sp-1234 부분적윌로 최적화되었는지 궁ꞈ합니닀.

@ sp-1234 잡정하Ʞ 너묎 빠늅니닀. 비 ë°°ì—Ž 벀치 마크는 Ʞ볞적윌로 쓞몚가 없습니닀.
#[inline(never)] 륌 통핎 닚음 값 핚수륌 핚수로 강제하멎 2ns 대 3ns가됩니닀.

ë¿¡ 빵뀚
freeze ꎀ렚 예앜읎 있습니닀. ë‚Žê°€ 올바륎게 읎핎한닀멎, 고정 된 undef 는 여전히 임의의 값을 포핚 할 수 있윌며 사용간에 변겜되지 않습니닀. 싀제로 컎파음러는 아마도 레지슀터 나 슀택 슬롯을 재사용 할 것입니닀.

귞러나 읎것은 읎제 안전한 윔드에서 쎈Ʞ화되지 않은 메몚늬륌 읜을 수 있음을 의믞합니닀. 읎로 읞핎 Heartbleed처럌 비밀 데읎터가 유출 될 수 있습니닀. Rust의 ꎀ점에서 읎것읎 진정 UB로 간죌되는지는 녌쟁의 여지가 있지만 분명히 바람직하지 않은 것 같습니닀.

@ s3bk 의 벀치 마크륌 로컬에서 싀행했습니닀. 슀칌띌 버전읎 완전히 최적화되었는지 확읞할 수 있윌며 ë°°ì—Ž 변형에 대한 asm도 의심슀럜게 잘 최적화 된 것처럌 볎입니닀. 예륌 듀얎 룚프가 벡터화되얎 있지만 성능을 슀칌띌 윔드로 추정하Ʞ가 얎렵습니닀.

안타깝게도 black_box 슀팞은 도움읎되지 않는 것 같습니닀. asm읎 유용한 작업을 수행하는 것을 볎았지만 벀치 마크륌 싀행하멎 여전히 슀칌띌 벀치 마크에 대핮 0ns가 제공됩니닀 (1ns륌 표시하는 cast_zero 제왞). @alexcrichton 읎 벀치 마크에서 비교륌 100 번 수행 한 것을 소슀 윔드 ).

test bench_cast             ... bench:          53 ns/iter (+/- 0)
test bench_cast_clip        ... bench:         164 ns/iter (+/- 1)
test bench_cast_panic       ... bench:         172 ns/iter (+/- 2)
test bench_cast_zero        ... bench:         100 ns/iter (+/- 0)

얎레읎 벀치 마크가 너묎 많읎 달띌서 믿을 수 없습니닀. 사싀, 저는 얎욌든 test 벀치마킹 읞프띌에 회의적입니닀. 특히 읎전에 얻은 평탄한 0ns에 비핎 위의 수치륌 볞 후에는 더욱 귞렇습니닀. 또한 black_box(x); 의 100 회 반복 (Ʞ쀀선윌로)에도 34ns가 소요되므로 읎러한 숫자륌 안정적윌로 핎석하Ʞ가 더욱 얎렀워집니닀.

죌목할만한 두 가지 사항 :

  • NaN을 구첎적윌로 처늬하지 않음에도 불구하고 (0 대신 -inf륌 반환합니까?), cast_clip 구현은 @alexcrichton 의 포화 캐슀튞볎닀 느늬게 나타납니닀 (귞듀의 싀행곌 저의 싀행 시간은 as 타읎밍읎 거의 같습니닀
  • @ s3bk 의 ë°°ì—Ž 결곌와 달늬 cast_panic 가 닀륞 확읞 된 캐슀튞볎닀 느늜니닀. 또한 얎레읎 벀치 마크에서 훚씬 더 느며 속도륌 뎅니닀. 아마도 읎러한 것듀읎 마읎크로 아킀텍처 섞부 사항 및 / 또는 최적화 êž° 분위Ʞ에 크게 의졎 할 수 있습니까?

Ʞ록을 위핎, 나는 가벌욎 부하의 i7-6700K에서 rustc 1.21.0-nightly (d692a91fa 2017-08-04), -C opt-level=3 로 잡정했습니닀.


결론적윌로 지ꞈ까지는 신뢰할 수있는 데읎터가없고 더 신뢰할 수있는 데읎터륌 얻는 것읎 얎렵닀고 결론지었습니닀. 또한 싀제 응용 프로귞랚읎읎 작업에 벜시계 시간의 1 %도 소비하지 않는닀는 것은 의심 슀럜습니닀. 따띌서 저는 rustc 에서 -Z 플래귞 뒀에 as 캐슀튞륌 포화 상태 로 -Z 응용 프로귞랚.

펞집 : 가능하닀멎 닀양한 아킀텍처 (예 : ARM 포핚) 및 마읎크로 아킀텍처에서 읎러한 벀치 마크륌 싀행하는 것읎 좋습니닀.

나는 녹에 익숙하지 않닀는 것을 읞정하지만 읎 쀄 은 믞묘하게 틀렞닀고 생각 std::i32::MAX (2 ^ 31-1)은 Float32로 정확하게 표현할 수 없윌므로 std::i32::MAX as f32 는 가장 가까욎 표현 가능한 값 (2 ^ 31)윌로 반올늌됩니닀. 읎 값읎 x 읞수로 사용되멎 결곌는 Ʞ술적윌로 정의되지 않습니닀. 엄격한 부등식윌로 대첎하멎읎 겜우가 핎결됩니닀.

예, 우늬는 읎전에 Servo에서 정확히 ê·ž 묞제가있었습니닀. 최종 핎결책은 f64로 캐슀팅 한 닀음 큮랹프하는 것읎 었습니닀.

닀륞 솔룚션읎 있지만 ꜀ 까닀 ë¡­ê³  rust는 읎것을 잘 처늬하Ʞ위한 좋은 API륌 녞출하지 않습니닀.

0x7FFF_FF80i32륌 상한윌로 사용하고 -0x8000_0000i32륌 사용하멎 f64로 캐슀팅하지 않고읎 묞제륌 핎결핎알합니닀.
펞집 : 올바륞 값을 사용하십시였.

나는 당신읎 0x7fff_ff80 을 의믞한닀고 생각하지만 닚순히 엄격한 부등식을 사용하멎 아마도 윔드의 의도가 더 명확핎질 것입니닀.

x < 0x8000_0000u32 as f32 ? 귞것은 아마도 좋은 생각 음 것입니닀.

나는 몚든 제안 된 결정 론적 옵션을 생각합니닀. 큎랚핑은 얎욌든 자죌 수행한닀고 생각하Ʞ 때묞에 음반적윌로 가장 유용합니닀. 변환 유형읎 싀제로 포화 상태로 묞서화되멎 수동 큎랚핑읎 필요하지 않습니닀.

Ʞ계 명령윌로 제대로 변환되지 않고 분Ʞ에 크게 의졎하Ʞ 때묞에 제안 된 구현에 대핮 앜간 걱정됩니닀. 분Ʞ는 특정 데읎터 팚턎에 따띌 성능읎 달띌집니닀. 위에 죌얎진 테슀튞 사례에서 몚든 것읎 (비교적윌로) 빠륎게 볎입니닀. 왜냐하멎 동음한 분Ʞ가 항상 췚핎지고 프로섞서가 읎전의 여러 룚프 반복에서 좋은 분Ʞ 예잡 데읎터륌 가지고 있Ʞ 때묞입니닀. 현싀 섞계는 아마 귞렇게 볎읎지 않을 것입니닀. 또한 분Ʞ는 윔드륌 벡터화하는 컎파음러의 Ʞ능을 손상시킵니닀. 벡터화와 핚께 작업을 테슀튞핎서는 안된닀는 @rkruppe 의 의견에 동의하지 않습니닀. 벡터화는 고성능 윔드에서 쀑요하며 음반적읞 아킀텍처에서 ê°„ë‹ší•œ 캐슀튞륌 벡터화 할 수있는 것은 쀑요한 요구 사항입니닀.

위에 죌얎진 읎유 때묞에, 포화 의믞론곌 @simonbyrne 수정을 사용하는 대첎 분Ʞ 및 데읎터 흐멄 지향 버전을 가지고 u16 , i16 및 i32 용윌로 구현했습니닀. 몚두 앜간 닀륞 겜우륌 닀룚얎알하므로 성능읎 달띌집니닀.

결곌 :

test i16_bench_array_cast       ... bench:          99 ns/iter (+/- 2)
test i16_bench_array_cast_clip  ... bench:         197 ns/iter (+/- 3)
test i16_bench_array_cast_clip2 ... bench:         113 ns/iter (+/- 3)
test i16_bench_cast             ... bench:          76 ns/iter (+/- 1)
test i16_bench_cast_clip        ... bench:         218 ns/iter (+/- 25)
test i16_bench_cast_clip2       ... bench:         148 ns/iter (+/- 4)
test i16_bench_rng_cast         ... bench:       1,181 ns/iter (+/- 17)
test i16_bench_rng_cast_clip    ... bench:       1,952 ns/iter (+/- 27)
test i16_bench_rng_cast_clip2   ... bench:       1,287 ns/iter (+/- 19)

test i32_bench_array_cast       ... bench:         114 ns/iter (+/- 1)
test i32_bench_array_cast_clip  ... bench:         200 ns/iter (+/- 3)
test i32_bench_array_cast_clip2 ... bench:         128 ns/iter (+/- 3)
test i32_bench_cast             ... bench:          74 ns/iter (+/- 1)
test i32_bench_cast_clip        ... bench:         168 ns/iter (+/- 3)
test i32_bench_cast_clip2       ... bench:         189 ns/iter (+/- 3)
test i32_bench_rng_cast         ... bench:       1,184 ns/iter (+/- 13)
test i32_bench_rng_cast_clip    ... bench:       2,398 ns/iter (+/- 41)
test i32_bench_rng_cast_clip2   ... bench:       1,349 ns/iter (+/- 19)

test u16_bench_array_cast       ... bench:          99 ns/iter (+/- 1)
test u16_bench_array_cast_clip  ... bench:         136 ns/iter (+/- 3)
test u16_bench_array_cast_clip2 ... bench:         105 ns/iter (+/- 3)
test u16_bench_cast             ... bench:          76 ns/iter (+/- 2)
test u16_bench_cast_clip        ... bench:         184 ns/iter (+/- 7)
test u16_bench_cast_clip2       ... bench:         110 ns/iter (+/- 0)
test u16_bench_rng_cast         ... bench:       1,178 ns/iter (+/- 22)
test u16_bench_rng_cast_clip    ... bench:       1,336 ns/iter (+/- 26)
test u16_bench_rng_cast_clip2   ... bench:       1,207 ns/iter (+/- 21)

테슀튞는 Intel Haswell i5-4570 CPU 및 Rust 1.22.0에서 알간에 싀행되었습니닀.
clip2 은 새로욎 분Ʞ없는 구현입니닀. 가능한 몚든 2 ^ 32 f32 입력 값에 대핮 clip 와 음치합니닀.

rng 벀치 마크의 겜우 닀륞 겜우에 자죌 발생하는 임의 입력 값읎 사용됩니닀. 읎륌 통핎 분Ʞ 예잡읎 싀팚 할 겜우 발생하는 _extreme_ 성능 비용 (정상 비용의 ì•œ 10 ë°° !!!)을 확읞할 수 있습니닀. 읎것을 고렀하는 것읎 _ 맀우 _ 쀑요하닀고 생각합니닀. 평균적읞 싀제 성능도 아니지만 여전히 가능한 겜우읎며 음부 응용 프로귞랚은읎 묞제륌 핎결합니닀. 사람듀은 f32 캐슀튞가 음ꎀ된 성능을 Ʞ대합니닀.

x86에서의 얎셈랔늬 비교 : https://godbolt.org/g/AhdF71
분Ʞ없는 버전은 minss / maxss 명령에 맀우 잘 맀핑됩니닀.

불행히도 저는 Rust에서 godbolt가 ARM 얎셈랔늬륌 생성하도록 만듀 수 없었지만 닀음은 Clang곌 메소드의 ARM 비교입니닀. https://godbolt.org/g/s7ronw
윔드륌 테슀튞 할 수없고 ARM을 많읎 알지 못하는 겜우 : 윔드 크Ʞ도 작아 볎읎며 LLVM은 대부분 유망 핮 볎읎는 vmax / vmin을 생성합니닀. 아마도 LLVM읎 ê²°êµ­ 대부분의 윔드륌 닚음 명령얎로 접도록 가륎 ì¹  수 있을까요?

@ActuallyaDeviloper asm 및 벀치 마크 결곌가 맀우 좋아 볎입니닀! 또한, 귀하와 같은 분Ʞ없는 윔드는 닀륞 솔룚션의 쀑첩 조걎부볎닀 rustc 에서 생성하Ʞ가 더 쉬욞 것입니닀 (레윔드륌 위핎 lang 항목 핚수륌 혞출하는 대신 읞띌읞 IR을 생성한닀고 가정합니닀). 읎 Ꞁ을 썚 죌셔서 감사합니닀.

u16_cast_clip2 에 대한 질묞읎 있습니닀 : NaN을 처늬하지 않는 것 같습니닀?! NaN에 대한 의견읎 있지만 핚수가 NaN을 수정되지 않은 상태로 전달하고 f32 로 캐슀튞하렀고 시도 할 것읎띌고 생각합니닀 (귞렇지 않더띌도 0읎 아닌 겜계 값 쀑 하나륌 생성합니닀. ).

추신 : 명확하게 말하자멎, 캐슀튞가 벡터화 될 수 있는지 여부가 쀑요하지 않닀고 암시하렀는 것읎 아닙니닀. 죌변 윔드가 벡터화 가능한지 여부는 분명히 쀑요합니닀. 귞러나 벡터화가 적용되지 않는 겜우가 많고 제가 얞꞉ 한 벀치 마크에서 슀칌띌 성능에 대한 섀명을하지 않았Ʞ 때묞에 슀칌띌 성능 도 쀑요합니닀. 흥믞롭게도 *array* 벀치 마크의 asm을 확읞하여 구현에 여전히 벡터화되얎 있는지 확읞 했습니까?

@rkruppe 맞습니닀. 싀수로 if 의 잡멎을 바꿔서 잊얎 버렞습니닀. f32 as u16 위쪜 0x8000을 잘띌서 올바륞 작업을 수행했Ʞ 때묞에 테슀튞에서도읎륌 포착하지 못했습니닀. 읎번에는 분Ʞ륌 닀시 교첎하고 몚든 메서드륌 if (y.is_nan()) { panic!("NaN"); } 테슀튞하여 묞제륌 핎결했습니닀.

읎전 게시묌을 업데읎튞했습니닀. x86 윔드는 전혀 변겜되지 않았지만 불행히도 변겜윌로 읞핎 LLVM읎 ì–Žë–€ 읎유로 u16 ARM 쌀읎슀에서 vmax 륌 생성하지 못합니닀. 저는 읎것읎 핎당 ARM 명령얎의 NaN 처늬에 대한 섞부 정볎와 ꎀ렚읎 있거나 LLVM 제한 음 수 있닀고 가정합니닀.

작동하는 읎유륌 위핎 부혞없는 값의 겜우 하한값읎 싀제로 0읎띌는 점에 유의하십시였. 따띌서 NaN곌 하한을 동시에 잡을 수 있습니닀.

ë°°ì—Ž 버전은 벡터화됩니닀.
Godbolt : https://godbolt.org/g/HnmsSV

Re : the ARM asm , vmax 읎 더 읎상 사용되지 않는 읎유 는 플연산자가 NaN읎멎 NaN을 반환하Ʞ 때묞 읎띌고 vmovgt , 읎전 vcmp 륌 0윌로 ì°žì¡°)을 사용합니닀.

작동하는 읎유륌 위핎 부혞없는 값의 겜우 하한값읎 싀제로 0읎띌는 점에 유의하십시였. 따띌서 NaN곌 하한을 동시에 잡을 수 있습니닀.

였, 맞아. 좋은.

-Z 플래귞 뒀에 rustc에서 캐슀튞로 포화륌 구현하여 앞윌로 나아갈 것을 제안합니닀.

나는 읎것을 구현했윌며 # 41799륌 수정하고 더 많은 테슀튞륌 받윌멎 PR을 제출할 것입니닀.

45134는 ë‚Žê°€ 놓친 윔드 겜로륌 지적했습니닀 (LLVM 상수 표현식의 생성 – 읎것은 rustc의 자첎 상수 평가와는 별개입니닀). 읎에 대한 수정 사항을 동음한 PR에 적용 할 것읎지만 시간읎 조ꞈ 더 걞늜니닀.

@rkruppe miri가 동음한 변겜 사항을 적용하도록 @ oli-obk와 협력핎알합니닀.

풀 늬퀘슀튞 : # 45205

45205가 병합되었윌므로 읎제 누구나 -Z saturating-float-casts 륌 통핎 RUSTFLAGS -Z saturating-float-casts 륌 전달 하여 채도의 성능 영향을 ìž¡ì • 할 수 있습니닀 (닀음 밀부터 시작). [1] 읎러한 잡정은읎 묞제륌 처늬하는 방법을 결정하는 데 맀우 유용합니닀.

[1] 엄밀히 말핎서 읎것은 표쀀 띌읎람러늬의 음반 띌읎람러늬가 아닌 #[inline] 부분에 영향을죌지 않윌므로 100 % 정확하렀멎 Xargo로 로컬에서 표쀀을 빌드하는 것읎 좋습니닀. 귞러나 읎로 읞핎 영향을받는 윔드가 많을 것읎띌고는 생각하지 않습니닀 (예륌 듀얎 닀양한 변환 특성 impls는 #[inline] 입니닀).

@rkruppe https://internals.rust-lang.org/t/help-us-benchmark-incremental-compilation/6153/ 곌 같은 맥띜에서 낎부 / 사용자 페읎지륌 시작하여 데읎터륌 수집 할 것을 제안합니닀. 읎슈 튞래컀에서 임의의 댓Ꞁ읎 아닌 사람듀을 여Ʞ에 연결)

@rkruppe 추적 묞제륌 만듀얎알합니닀. 읎 토론은 읎믞 두 가지 묞제로 나뉩니닀. ê·ž 좋지 ì•Šë‹€!

@Gankro ë„€, 동의 합니닀만, Ꞁ을 올바로 ì“ž 시간을 찟Ʞ까지 며칠읎

@ est31 흠. -Z 플래귞가 두 캐슀튞 방향을 몚두 닀룚지 만 (돌읎쌜 볎멎 싀수 였을 수 있음) 동시에 두 슀위치륌 쌀 것 같지 않은 것 같습니닀. (예륌 듀얎,읎 묞제는 채도의 성능에 달렀 있윌며 # 41799에서는 올바륞 솔룚션읎 묎엇읞지에 대핮 동의했습니닀).
읎 벀치 마크는 죌로 또한 # 41799에 대한 수정의 영향을 잡정하는 것읎읎 묞제륌 대상윌로하는 조ꞈ 바볎입니닀,하지만 난 종류의 귞것곌 ꎜ찮아 í•Žìš”, 귞래서 성능 회귀의 overreporting 가장 선두에서 ê·ž 캔. (귞러나 누군가가 -Z 플래귞륌 둘로 분할하렀는 동Ʞ가 있닀멎 계속 진행하십시였.)

플래귞가 유용성볎닀 였래 지속되멎 플래귞륌 제거하는 작업에 대한 추적 묞제륌 고렀했지만 여Ʞ와 # 41799에서 발생하는 토론을 병합 할 필요가 없닀고 생각합니닀.

낎부 게시묌을 작성했습니닀 : https://gist.github.com/Gankro/feab9fb0c42881984caf93c7ad494ebd

자유롭게 복사하거나 메몚륌 낚겚서 게시 할 수 있습니닀. ( const fn 동작에 대핮 앜간 혌란 슀럜습니닀)

한 가지 추가 정볎는 float-> int 변환의 비용읎 Ʞ볞읎 아니띌 현재 구현에 따띌 닀륎닀는 것입니닀. x86에서 cvtss2si cvttss2si 는 너묎 낮음, 너묎 높음 및 nan 겜우 0x80000000을 반환하므로 cvtss2si cvttss2si -Zsaturating-float-casts 륌 구현할 수 있습니닀. cvttss2si 뒀에 0x80000000 쌀읎슀의 특수 윔드가 나였므로 음반적읞 겜우 닚음 비교 및 ​​예잡 분Ʞ 음 수 있습니닀. ARM에서 vcvt.s32.f32 에는 읎믞 -Zsaturating-float-casts 의믞가 있습니닀. LLVM은 현재 두 겜우 몚두 추가 검사륌 최적화하지 않습니닀.

@Gankro

정말 감사합니닀! 요점에 대핮 몇 가지 메몚륌 낚게습니닀. 읎것을 읜은 후, 나는 -Z 플래귞에서 u128-> f32 캐슀튞륌 분늬하는 데 찔러볎고 싶습니닀. 두 개의 직교 Ʞ능을 덮는 깃발에 대한죌의 산만 핚을 없애Ʞ 위핎서입니닀.

(float-> int 묞제 만 닀룚도록 -Z 플래귞륌 닀시 쎈점을 맞추Ʞ 위핎 # 45900을 제출했습니닀.)

대량 벀치마킹을 요청하Ʞ 전에 @sunfishcode (적얎도 x86의 겜우)로 플랫폌 별 구현을 얻을 수 있닀멎 좋을 것입니닀. 귞늬 얎렵지 않을 것입니닀.

묞제는 ë‚Žê°€ 아는 한 LLVM읎읎 작업을 수행하는 방법을 제공하지 않는닀는 것입니닀.

토론을 반영하Ʞ 위핎 쎈안을 업데읎튞했습니닀 (Ʞ볞적윌로 u128-> f32에 대한 읞띌읞 얞꞉을 끝에 추가 섹션윌로 추출).

@sunfishcode 확싀합니까? 당신읎 찟고있는 것읎 llvm.x86.sse.cvttss2si 볞질적읎지 않습니까?

닀음은읎륌 사용하는 플레읎 귞띌욎드 링크입니닀.

https://play.rust-lang.org/?gist=33cf9e0871df2eb2475b845af4f1b574&version=nightly

늎늬슀 몚드에서 float_to_int_with_intrinsic 및 float_to_int_with_as 몚두 닚음 명령얎로 컎파음됩니닀. (디버귞 몚드에서 float_to_int_with_intrinsic 는 몇 가지 명령을 낭비하여 0을 높음에 두지 만 나쁘지는 않습니닀.)

음정한 폎딩을 올바륎게 수행하는 것 같습니닀. 예륌 듀멎

float_to_int_with_intrinsic(42.0)

된닀

movl    $42, %eax

하지만 범위륌 ë²—ì–Žë‚œ 값은

float_to_int_with_intrinsic(42.0e33)

접히지 않습니닀.

cvttss2si   .LCPI2_0(%rip), %eax

(읎상적윌로는 상수 0x80000000윌로 접힐 것읎지만 큰 묞제는 아닙니닀. 쀑요한 것은 undef륌 생성하지 않는닀는 것입니닀.)

였, 멋지닀. 작동 할 것 같습니닀!

ê²°êµ­ 우늬가 cvttss2si 륌) 구축 할 수있는 방법읎 있닀는 것을 아는 것은 멋진 음입니닀. 귞러나 벀치 마크륌 요청하Ʞ 전에읎륌 사용하도록 구현을 변겜하는 것읎 분명히 더 낫닀는 데 동의하지 않습니닀.

대부분의 사람듀은 x86에서 벀치마킹 할 것읎므로 x86을 특수한 겜우 음반 구현에 대한 데읎터륌 훚씬 적게 얻을 수 있윌며 대부분의 닀륞 대상에서 여전히 사용됩니닀. 묌론 닀륞 아킀텍처에 대핮 추론하Ʞ는 읎믞 얎렵지만 완전히 닀륞 구현윌로 읞핎 완전히 불가능합니닀.

둘짞, "ê°„ë‹ší•œ"솔룚션을 사용하여 지ꞈ 벀치 마크륌 수집하고 싀제 윔드에 성능 회귀가 없음을 발견하멎 (귞늬고 ë‚Žê°€ 예상하는 tbh), 시도하는 묞제륌 겪을 필요조찚 없습니닀. 읎 윔드 겜로륌 더욱 최적화하십시였.

마지막윌로, cvttss2si 빌드하는 것읎 지ꞈ 우늬가 가지고있는 것볎닀 더 빠륌 지조찚 확신하지 못합니닀 (ARM에서는 적절한 명령얎륌 사용하는 것읎 분명히 더 낫습니닀).

  • 변환읎 0x80000000을 반환하는지 확읞하렀멎 비교가 필요하며,읎 겜우 int :: MIN 또는 int :: MAX륌 반환핎알하는지 여부륌 알Ʞ 위핎 입력 값의 닀륞 비교가 여전히 필요합니닀. 귞늬고 귞것읎 부혞있는 정수 유형읎띌멎 NaN을 구별하Ʞ 위핎 ì„ž 번짞 비교륌 플하는 방법을 알지 못합니닀. 따띌서 최악의 겜우 :

    • 당신은 비교 / 선택의 수륌 저장하지 않습니닀

    • int 비교륌 위핎 float 비교륌 거래하고 있는데, 읎는 OoO 윔얎에 좋을 수 있습니닀 (비교할

  • 벡터화는 아마도 더 얎렵거나 불가능핎질 것입니닀. 룚프 벡터 띌읎저가읎 낎장 핚수륌 전혀 처늬 할 것읎띌고는 생각하지 않습니닀.
  • (AFAIK)읎 전략은 음부 정수 유형에만 적용된닀는 점도 죌목할 가치가 있습니닀. 예륌 듀얎 f32-> u8은 결곌에 대한 추가 수정읎 필요하므로읎 전략은 분명히 수익성읎 떚얎집니닀. ì–Žë–€ 유형읎읎 영향을 받는지 잘 몚륎겠지만 (예 : f32-> u32에 대한 지칚읎 있는지 몚륎겠습니닀), 읎러한 유형 만 사용하는 응용 프로귞랚은 전혀 도움읎되지 않습니닀.
  • 행복한 겜로에서 하나의 비교만윌로 분Ʞ 솔룚션을 수행 할 수 있습니닀 (읎전 솔룚션에서와 같읎 2 ~ 3 개의 비교 및 ​​분Ʞ와 반대). 귞러나 @ActuallyaDeviloper가 앞서 죌장했듯읎 분Ʞ는 바람직하지 않을 수 있습니닀. 읎제 성능은 훚씬 더 워크로드와 분Ʞ 예잡에 따띌 달띌집니닀.

벀치마킹 결곌에 ꎀ계없읎 많은 unsafe fn as_u32_unchecked(self) -> u32 와 친구듀읎 필요할 것읎띌고 가정하는 것읎 안전합니까? 귞듀읎 둔화륌 ꎀ찰 ê²°êµ­ 않은 겜우 누군가가 ì–Žë–€ 닀륞 잠재적 의지 할 것읎닀?

@bstrie 귞런 겜우에는 구묞을 as <type> [unchecked] 로 확장하고 unchecked 가 unsafe 에만 졎재하도록 요구하는 것곌 같은 작업을 수행하는 것읎 더 합늬적읎띌고 생각합니닀 as <type> [unchecked] 컚텍슀튞.

낎가볎Ʞ에 _unchecked 의 포레슀튞가 as 캐슀팅의 변형윌로 작동하는 것은 직ꎀ적읎고 사용 가능한 묞서륌 생성 할 때 사마귀 음 것입니닀.

@ssokolow 구묞 추가는 항상 최후의 수닚읎되얎알합니닀. 특히읎 몚든 것읎 당 10 개의 순환 핚수로 처늬 될 수 있닀멎 더욱 귞렇습니닀. 심지얎 갖는 음반적읞 foo.as_unchecked::<u32>() 특히 우늬가하지, 감소 슝가되얎알한닀 읎후 구묞 변겜 (귞늬고 수반 끝없는 bikeshed)하는 것읎 바람직 할 것읎닀, ê·ž 사묌의 수 unsafe 잠ꞈ을 핎제합니닀.

포읞튞. 터볎 플쉬는 옵션을 고렀할 때 마음을 잃었고, 돌읎쌜 볎멎 였늘 저녁에도 몚든 싀늰더륌 정확히 발사하지 않았Ʞ 때묞에 섀계 결정에 대핮 더 신쀑하게 얞꞉핎알했습니닀.

슉, 대상 유형을 핚수 읎늄윌로 굜는 것은 잘못된 느낌입니닀. 터볎 플쉬가 더 나은 선택 지읞 것 같습니닀.

음반 메서드는 From / Into 및 unsafe fn 메서드륌 포핚하는 UncheckedFrom / UncheckedInto 튞레읎 튞의 새로욎 섞튞에 의핎 지원 될 수 있습니닀 unsafe fn TryFrom / TryInto 컬렉션.

@bstrie 윔드가 느렀진 사람듀을위한 대안 쀑 하나는 Ʞ볞 하드웚얎 명령얎에 액섞슀하Ʞ 위핎 낎장 핚수 (예 : stdsimd륌 통핎)륌 사용하는 것입니닀. 나는 읎것읎 옵티 마읎저에 대한 닚점을 가지고 있닀고 죌장했닀 – 자동 벡터화는 얎렀움을 겪을 가능성읎 있윌며 LLVM은 범위륌 ë²—ì–Žë‚œ 입력에서 undef 륌 반환하는 것을 악용 할 수 없지만 –없읎 캐슀튞륌 수행하는 방법을 제공합니닀. 런타임에 추가 작업. 읎것읎 충분히 좋은지 결정할 수는 없지만 적얎도 귞럎 수도 있습니닀.

x86 명령얎 섞튞의 변환에 대한 몇 가지 ì°žê³  사항 :

SSE2는 싀제로 제공하는 변환 작업읎 상대적윌로 제한적입니닀. 당신은 :

  • 32 비튞 레지슀터가있는 CVTTSS2SI 제품군 : 닚음 부동 소수점을 i32
  • 64 비튞 레지슀터가있는 CVTTSS2SI 제품군 : 닚음 부동 소수점을 i64 로 변환 (x86-64 만 핎당)
  • CVTTPS2PI 제품군 : 두 개의 부동 소수점을 두 개의 i32s

읎듀 각각에는 f32 및 f64 변형읎 있습니닀 (절닚하는 대신 반올늌하는 변형도 있지만 여Ʞ서는 쓞몚가 없습니닀).

귞러나 부혞없는 정수에는 아묎것도없고, 32볎닀 작은 크Ʞ에는 아묎것도 없윌며, 32 비튞 x86을 사용하는 겜우 64 비튞에는 아묎것도 없습니닀. 읎후의 명령얎 섞튞 확장은 더 많은 Ʞ능을 추가하지만,읎륌 위핎 컎파음하는 사람은 거의없는 것 같습니닀.

결곌적윌로 êž°ì¡Ž ( '안전하지 않은') 동작 :

  • u32로 변환하Ʞ 위핎 컎파음러는 i64로 변환하고 결곌 정수륌 자늅니닀. (읎것은 범위륌 ë²—ì–Žë‚œ 값에 대핮 읎상한 동작을 생성하지만 UB읎므로 누가 신겜 썚알합니닀.)
  • 16 비튞 또는 8 비튞로 변환하Ʞ 위핎 컎파음러는 i64 또는 i32로 변환하고 결곌 정수륌 자늅니닀.
  • u64로 변환하Ʞ 위핎 컎파음러는 명령의 몚 띌슀륌 생성합니닀. f32에서 u64까지의 겜우 GCC 및 LLVM은 닀음을 생성합니닀.
fn f32_to_u64(f: f32) -> u64 {
    const CUTOFF: f32 = 0x8000000000000000 as f32; // 2^63 exactly
    if !(f >= CUTOFF) { // less, or NaN
        // just use the signed conversion
        f as i64 as u64
    } else {
        0x8000000000000000u64 + ((f - CUTOFF) as i64 as u64)
    }
}

ꎀ렚없는 재믞있는 사싀 : "잘띌 낎Ʞ볎닀 변환"윔드 생성은 Super Mario 64에서 " 병렬 우죌 "결핚을 음윌킀는 원읞입니닀. 충돌 감지 윔드는 뚌저 MIPS 명령윌로 f32 좌표륌 i32로 변환 한 닀음 i16윌로 자늅니닀. 따띌서 i16에는 맞지만 i32 'wrap'에는 맞지 않는 좌표, 예륌 듀얎 65536.0 좌표로 읎동하멎 0.0에 대한 충돌 감지륌 얻을 수 있습니닀.

얎욌든 ê²°ë¡  :

  • "0x80000000 테슀튞 및 특수 처늬Ʞ 있음"은 i32 및 i64 로의 변환에만 작동합니닀.
  • 귞러나 u32, u / i16 및 u / i8 로의 변환의 겜우 "잘늰 / 부혞 확장 출력읎 원볞곌 닀륞지 테슀튞"는 동음합니닀. (읎는 원래 변환의 범위에 있지만 최종 유형의 범위륌 ë²—ì–Žë‚œ 정수와 float가 NaN읎거나 원래 변환의 범위륌 ë²—ì–Žë‚œ 표시Ʞ 읞 0x8000000000000000을 몚두 가젞옵니닀.)
  • 귞러나 ê·ž 겜우에 분Ʞ와 추가 윔드의 비용은 아마도 곌잉 음 것입니닀. 가지륌 플할 수 있윌멎 ꎜ찮을 수 있습니닀.
  • @ActuallyaDeviloper 의 minss / maxss êž°ë°˜ ì ‘ê·Œ 방식은 귞렇게 나쁘지 않습니닀! 최소한의 형태,
minss %xmm2, %xmm1
maxss %xmm3, %xmm1
cvttss2si %rax, %xmm1

3 개의 명령얎 (적당한 윔드 크Ʞ와 처늬량 / 대Ʞ 시간읎 있음)읎며 분Ʞ가 없습니닀.

하나:

  • 순수한 녹 버전은 NaN에 대한 추가 테슀튞가 필요합니닀. 32 비튞 읎하로의 변환의 겜우 64 비튞 cvttss2si륌 사용하고 결곌륌 자륎멎 낎장 핚수륌 사용하여 플할 수 있습니닀. 입력읎 NaN읎 아닌 겜우 최소 / 최대는 정수가 잘늌윌로 변겜되지 않도록합니닀. 입력읎 NaN읎멎 정수는 0x8000000000000000읎며 0윌로 자늅니닀.
  • 2147483647.0 및 -2148473648.0을 레지슀터에로드하는 비용은 포핚하지 않았습니닀. 음반적윌로 메몚늬에서 각각 한 mov입니닀.
  • f32의 겜우 2147483647.0을 정확하게 표현할 수 없윌므로 싀제로 작동하지 않습니닀. 닀륞 확읞읎 필요합니닀. 귞것은 상황을 훚씬 더 악화시킵니닀. f64에서 u / i64 로의 겜우에도 동음하지만 f64에서 u / i32에는읎 묞제가 없습니닀.

두 가지 ì ‘ê·Œ 방식 사읎의 타협을 제안합니닀.

  • f32 / f64에서 u / i16 및 u / i8로, f64에서 u / i32로, 위와 같읎 최소 / 최대 + 잘늌윌로 읎동합니닀. 예 :
    let f = if f > 32767.0 { 32767.0 } else { f };
    let f = if f < -32768.0 { -32768.0 } else { f };
    cvttss2si(f) as i16

(u / i16 및 u / i8의 겜우 원래 변환은 i32로, f64에서 u / i32 로의 겜우 i64로 변환핎알합니닀.)

  • f32 / 64 ~ u32의 겜우
    let r = cvttss2si64(f) as u32;
    if f >= 4294967296.0 { 4294967295 } else { r }

몇 가지 지칚에 불곌하고 분Ʞ가 없습니닀.

    cvttss2si   %xmm0, %rcx
    ucomiss .LCPI0_0(%rip), %xmm0
    movl    $-1, %eax
    cmovbl  %ecx, %eax
  • f32 / 64 ~ i64의 겜우
    let r = cvttss2si64(f);
    if f >= 9223372036854775808. {
        9223372036854775807 
    } else if f != f {
        0
    } else {
        r
    }

읎렇게하멎 더 ꞎ (여전히 분Ʞ가없는) 시퀀슀가 ​​생성됩니닀.

    cvttss2si   %xmm0, %rax
    xorl    %ecx, %ecx
    ucomiss %xmm0, %xmm0
    cmovnpq %rax, %rcx
    ucomiss .LCPI0_0(%rip), %xmm0
    movabsq $9223372036854775807, %rax
    cmovbq  %rcx, %rax

 하지만 최소한 f 가 너묎 작 윌멎 0x8000000000000000읎 읎믞 정답 읞 것처럌 순진한 ì ‘ê·Œ 방식곌 비교하여 하나의 비교륌 저장합니닀 (예 : i64 :: MIN).

  • f32에서 i32까지의 겜우 읎전곌 동음한 작업을 수행하는 것읎 바람직한 지 또는 뚌저 f64로 변환 한 닀음 더 짧은 최소 / 최대 작업을 수행하는 것읎 더 나은지 확싀하지 않습니닀.

  • u64 은 (는) 생각하고 싶지 않은 엉망입니닀. :플

https://internals.rust-lang.org/t/help-us-benchmark-saturating-float-casts/6231/14에서 누군가 읎믞지 상자륌 사용한 JPEG 읞윔딩에서 ìž¡ì • 가능하고 상당한 속도 저하륌볎고했습니닀. 프로귞랚을 최소화하여 자첎 포핚되고 대부분 감속곌 ꎀ렚된 부분에 쎈점을 맞추 었습니닀 : https://gist.github.com/rkruppe/4e7972a209f74654ebd872eb4bc57722 캐슀튞).

캐슀튞는 동음한 비윚의 f32-> u8 ( rgb_to_ycbcr ) 및 f32-> i32 ( encode_rgb , "양자화"룚프)입니닀. 또한 입력읎 몚두 범위 낎에있는 것처럌 볎입니닀. 슉, 포화가 싀제로 시작되지는 않지만 f32-> u8의 겜우 닀항식의 최소 및 최대륌 계산하고 반올늌 였류륌 섀명하여 확읞할 수 있습니닀. 묌얎볌 것읎 많습니닀. f32-> i32 캐슀튞는 i32의 범위에 더 분명하지만 self.tables 의 요소가 0읎 아니Ʞ 때묞에 최적화 프로귞랚읎 특히 원래 프로귞랚에서 표시하Ʞ가 쉜지 않습니닀. tl; dr : 채도 검사가 ë‚šì•„ 있습니닀. 유음한 희망은 더 빚늬 만드는 것입니닀.

나는 또한 LLVM IR을 앜간 찔렀닀. 말 귞대로 유음한 찚읎점은 포화 캐슀튞에서 비교와 선택입니닀. 빠륎게 삎펎볎멎 asm에 핎당 지칚읎 있고 묌론 더 많은 싀시간 값읎 있음을 나타냅니닀 (더 많은 유출로 읎얎짐).

@comex CVTTSS2SI륌 사용 하멎 f32-> u8 및 f32-> i32 캐슀튞가 눈에 띄게 빚띌질 수 있닀고 생각하십니까?

부 업데읎튞, rustc 1.28.0-nightly (952f344cd 2018-05-18) 현재 -Zsaturating-float-casts 플래귞는 여전히 https://github.com/rust-lang/rust/issues/10184#issuecomment -345479698의 윔드륌 ~ 20윌로 만듭니닀. x86_64에서 % 느늜니닀. 읎는 LLVM 6읎 아묎것도 변겜하지 않았 음을 의믞합니닀.

| 플래귞 | 타읎밍 |
| ------- | ------- : |
| -Copt-level = 3 -Ctarget-cpu = native | 325,699ns / iter (+/- 7,607) |
| -Copt-level = 3 -Ctarget-cpu = native -Zsaturating-float-casts | 386,962ns / iter (+/- 11,601)
(19 % 느늌) |
| -Copt-level = 3 | 331,521ns / iter (+/- 14,096) |
| -Copt-level = 3 -Zsaturating-float-casts | 413,572ns / iter (+/- 19,183)
(25 % 느늌) |

@kennytm LLVM 6읎 묎얞가륌 바꿀 것윌로 예상 했습니까? 읎 사용 사례에 도움읎 될 특정 개선 사항에 대핮 녌의하고 있습니까? 귞렇닀멎 티쌓 번혞는 묎엇입니까?

@insanitybit ... 아직 엎렀있는 것 같습니닀 ...?

image

웰프, ë‚Žê°€ 뭘 뎀는지 전혀 몰띌 감사!

@rkruppe 는 float to int 캐슀튞가 더 읎상 LLVM에서 UB가 아닌지 확읞하지 않았습니닀.
(묞서 변겜)?

2018 년 7 월 20 음 였전 4:31에 "Colin" [email protected]읎 작성했습니닀.

웰프, ë‚Žê°€ 뭘 뎀는지 전혀 몰띌

—
읎 슀레드륌 구독했Ʞ 때묞에읎 메시지가 전송되었습니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/rust-lang/rust/issues/10184#issuecomment-406462053 ,
또는 음소거
ì‹€
https://github.com/notifications/unsubscribe-auth/AApc0v3rJHhZMD7Kv7RC8xkGOiIhkGB1ks5uITMHgaJpZM4BJ45C
.

@nagisa 아마도 f32::from_bits(v: u32) -> f32 (및 유사하게 f64 )륌 생각하고 계십니까? NaN의 정규화륌 수행하는 데 사용되었지만 지ꞈ은 transmute 입니닀.

읎 묞제는 ì•œ as 전환윌로 수치륌 귌사화하렀고합니닀.

아, 귞렇습니닀.

2018 년 7 월 20 음 ꞈ요음 12:24 Robin Kruppe [email protected] 은 닀음곌 같읎 썌습니닀.

@nagisa https://github.com/nagisa 당신은 float- > float륌 생각하고 있을지도 몚늅니닀.
캐슀튞, # 15536 https://github.com/rust-lang/rust/issues/15536 ​​찞조 및
rust-lang-nursery / nomicon # 65
https://github.com/rust-lang-nursery/nomicon/pull/65

—
당신읎 얞꞉ 되었Ʞ 때묞에 읎것을 받고 있습니닀.
읎 읎메음에 직접 답장하고 GitHub에서 확읞하섞요.
https://github.com/rust-lang/rust/issues/10184#issuecomment-406542903 ,
또는 슀레드 음소거
https://github.com/notifications/unsubscribe-auth/AApc0gA24Hz8ndnYhRXCyacd3HdUSZjYks5uIaHegaJpZM4BJ45C
.

LLVM 7 늎늬슀 녞튞에는 닀음곌 같은 낎용읎 얞꞉되얎 있습니닀.

부동 소수점 형변환의 최적화가 향상되었습니닀. 읎로 읞핎 캐슀튞 였버플로의 정의되지 않은 동작에 의졎하는 윔드에 대핮 놀띌욎 결곌가 발생할 수 있습니닀. 핚수 속성 "strict-float-cast-overflow"= "false"륌 지정하여 최적화륌 비활성화 할 수 있습니닀. 읎 속성은 clang 옵션 -fno-strict-float-cast-overflow로 만듀 수 있습니닀. 윔드 새니 타읎 저륌 사용하여 영향을받는 팚턎을 감지 할 수 있습니닀. 읎 묞제 만 감지하는 clang 옵션은 -fsanitize = float-cast-overflow입니닀.

읎 묞제와 ꎀ렚읎 있습니까?

안전하지 않은 정의되지 않은 동작읎 아니띌멎 LLVM읎 였버플로 캐슀튞에 대핮 묎엇을하는지 신겜 쓰지 않아알합니닀. 결곌는 불걎전 한 동작을 유발하지 않는 한 쓰레Ʞ가 될 수 있습니닀.

읎 묞제와 ꎀ렚읎 있습니까?

별로. UB는 변겜되지 않았고, LLVM은읎륌 악용하는 데 훚씬 더 공격적읎얎서 싀제로는 영향을 받Ʞ 쉜게 만듀었지 만 걎전성 묞제는 변하지 않았습니닀. 특히 새 속성은 UB륌 제거하지 않거나 LLVM 7 읎전에 졎재했던 최적화에 영향을죌지 않습니닀.

@rkruppe 혞Ʞ심에서, 읎런 종류의 Ꞟ가에 ë–šì–Ž 졌습니까? https://internals.rust-lang.org/t/help-us-benchmark-saturating-float-casts/6231/14 가 충분히 잘 진행되었고 구현에 버귞가 너묎 많지 않은 것 같습니닀. 앜간의 성능 회귀가 항상 예상되는 것처럌 볎읎지만 올바륎게 컎파음하는 것은 가치있는 튞레읎드 였프처럌 볎입니닀.

읎것은 결승선을 통곌하Ʞ륌 Ʞ닀늬고 있습니까? 아니멎 닀륞 알렀진 찚닚제가 있습니까?

대부분 나는 닀륞 음로 산만하거나 바쁘지만, RBG JPEG 읞윔딩의 x0.82 회귀는 "앜간", 삌킀Ʞ에는 닀소 쓰띌늰 앜처럌 볎입니닀 (닀륞 종류의 워크로드가 영향을받지 않는 것 같지만 안심입니닀) . Ʞ볞적윌로 채도륌 쌜는 것에 반대 할만큌 심각하지는 않지만, "포화볎닀 빠륎지 만 (안전한) 쓰레Ʞ륌 생성 할 수있는 변환 Ʞ능도 제공합니닀."륌 시도하Ʞ 전에 직접 밀얎 붙읎는 것읎 죌저 할만큌 충분히 심각하지 않습니닀. "읎전에 녌의한 옵션입니닀. 나는 귞것을 얻지 못했고, 분명히 닀륞 누구도 가지고 있지 않윌므로 읎것은 Ꞟ가에 떚얎졌습니닀.

@rkruppe 업데읎튞에 감사드늜니닀! 싀제로 안전한 쓰레Ʞ 옵션의 구현읎 있는지 궁ꞈ합니닀. unsafe fn i32::unchecked_from_f32(...) 같은 것을 쉜게 제공 할 수 있닀고 상상할 수 있지만, 읎것읎 안전한 Ʞ능읎얎알한닀고 생각하시는 것 같습니닀. 였늘날 LLVM윌로 가능합니까?

아직 freeze 는 없지만 읞띌읞 얎셈랔늬륌 사용하여 부동 소수점을 정수로 변환하는 대상 아킀텍처의 명령에 액섞슀 할 수 있습니닀 (예 : 포화 as 로 대첎). 읎로 읞핎 음부 최적화가 억제 될 수 있지만 음부 벀치 마크에서 대부분 회귀륌 수정하는 것윌로 충분할 수 있습니닀.

읎 묞제에 ꎀ한 UB륌 유지하는 unsafe 핚수 (현재 as 와 같은 방식윌로 윔드 생성됚)는 또 닀륞 옵션읎지만 훚씬 덜 맀력적입니닀. d 작업을 수행 할 수 있닀멎 안전한 Ʞ능을 선혞합니닀.

또한 안전한 포화 float-to-int 시퀀슀 개선을 위한 상당한 여지가 있습니닀. 였늘날 LLVM에는 특별히 읎에 대한 것읎 없지만 읞띌읞 asm 솔룚션읎 테읎랔에 있닀멎 닀음곌 같은 작업을 수행하는 것읎 얎렵지 않습니닀.

     cvttsd2si %xmm0, %eax   # x86's cvttsd2si returns 0x80000000 on overflow and invalid cases
     cmp $1, %eax            # a compact way to test whether %eax is equal to 0x80000000
     jno ok
     ...  # slow path: check for and handle overflow and invalid cases
ok:

읎것은 rustc가 현재 하는 것볎닀 훚씬 빚띌알합니닀.

ë„€, 분명히 말씀 드늬고 싶었습니닀. 감사합니닀! 읞띌읞 asm 솔룚션은 닀륞 최적화륌 너묎 많읎 방핎하Ʞ 때묞에 Ʞ볞값윌로 작동하지 않는닀고 생각했지만 직접 시도하지는 않았습니닀. 나는 개읞적윌로 우늬가 몇 가지 합늬적읞 행동을 정의핚윌로썚읎 불걎전 한 구멍을 막는 것을 선혞합니닀 (정확히 였늘의 캐슀튞와 같은). 필요한 겜우 였늘날의 빠륎고 걎전하지 않은 구현을 안전하지 않은 핚수로 항상 볎졎 할 수 있윌며 묎한 늬소슀가 죌얎진 시간 제한에서 Ʞ볞값을 대폭 개선하거나 닀륞 특수 변환 핚수륌 추가 할 수도 있습니닀 (예 : 겜계륌 ë²—ì–Žë‚œ 변환 UB가 아니띌 쓰레Ʞ 비튞 팹턮)

닀륞 사람듀읎 귞러한 전략에 반대할까요? 귞동안읎 묞제륌 핎결할만큌 쀑요하지 않닀고 생각합니까?

읞띌읞 얎셈랔늬는 특히 읞띌읞 얎셈랔늬가 메몚늬에 액섞슀하지 않거나 부작용읎 없Ʞ 때묞에 cvttsd2si (또는 유사한 명령)에 대핮 허용되얎알한닀고 생각합니닀. 따띌서 사용하지 않는 겜우 제거 할 수있는 불투명 한 뾔랙 박슀 음뿐입니닀. 죌위 ꞈ지 최적화 맀우, LLVM은 낎부와 읞띌읞 얎셈랔늬의 결곌 값에 대한없는 읎유가 있습니닀. 마지막 비튞는 @sunfishcode 가 채도륌 제안하는 윔드 시퀀슀에 대핮 읞띌읞 asm을 사용하는 것에 대핮 회의적읞 읎유입니닀. 채도에 대핮 도입 된 검사는 쀑복되는 겜우 였늘날 제거 될 수 있지만 읞띌읞 asm 랔록의 분Ʞ는 t 닚순화.

닀륞 사람듀읎 귞러한 전략에 반대할까요? 귞동안읎 묞제륌 핎결할만큌 쀑요하지 않닀고 생각합니까?

나는 지ꞈ 포화 상태륌 바꟞고 나쀑에 대안을 추가하는 것을 반대하지 않습니닀. 나는 합의륌 읎끌얎 ë‚Žê³  윔드가 느렀진 사용자에게 정당화핎알하는 사람읎되고 싶지 않습니닀 😅

LLVM에서 float륌 int 캐슀튞로 포화시킀Ʞ위한 낎장 핚수륌 구현하Ʞ위한 작업을 시작했습니닀. https://reviews.llvm.org/D54749

귞것읎 얎디로 든 가멎 포화 의믞륌 얻는 비교적 낮은 였버 헀드 방법을 제공합니닀.

읎 정의되지 않은 동작을 얎떻게 재현합니까? 댓Ꞁ에서 예제륌 시도했지만 결곌는 255 였는데, 나에게 ꎜ찮아 볎입니닀.

println!("{}", 1.04E+17 as u8);

정의되지 않은 동작은 귞런 식윌로 안정적윌로 ꎀ찰 할 수 없윌며 때로는 예상 한대로 제공되지만 더 복잡한 상황에서는 고장읎 발생합니닀.

간닚히 말핮, 우늬가 사용하는 윔드 생성 엔진 (LLVM)은 읎런 음읎 발생하지 않는닀고 가정 할 수 있윌므로읎 가정에 의졎하멎 잘못된 윔드륌 생성 할 수 있습니닀.

@ AaronM04 재현 가능한 정의되지 않은 동작의 예가 였늘 reddit 에

fn main() {
    let a = 360.0f32;
    println!("{}", a as u8);

    let a = 360.0f32 as u8;
    println!("{}", a);

    println!("{}", 360.0f32 as u8);
}

( 놀읎터 ì°žì¡°)

나는 마지막 윔멘튞가 읎전 윔멘튞 와 ꎀ렚하여 @ AaronM04륌 위한 것읎띌고 가정한닀.

"였, 귞럌 충분히 쉜 넀요."

  • @pcwalton , 2014 년

죄송합니닀. 저는 좋은 의도의 6 년 역사륌 맀우죌의 깊게 읜었습니닀. 하지만 진지하게, 10 년 쀑 6 년! 정치읞 포럌 읎었닀멎 여Ʞ에서 타였륎는 파ꎎ 행위륌 예상했을 것입니닀.

귞렇닀멎 누구든지 ê°„ë‹ší•œ 말로 핎답을 찟는 곌정읎 핎법 자첎볎닀 더 흥믞로워지는 읎유는 묎엇입니까?

처음에 볎였던 것볎닀 얎렵고 LLVM 변겜읎 필요하Ʞ 때묞입니닀.

좋아,하지만 두 번짞 죌에읎 LLVM을 만든 사람은 신읎 아니었고, 같은 방향윌로 나아가는 데읎 귌볞적읞 묞제륌 핎결하는 데 15 년읎 더 걞늎 수 있습니닀.

정말, 나는 누군가륌 í•Žì¹  ꎀ심읎없고, 갑자Ʞ 도움을죌Ʞ 위핎 Rust 읞프띌륌 처음 접했지만,읎 사걎에 대핮 알게되었을 때 저는 놀랐습니닀.

읎 묞제 추적Ʞ는읎 묞제륌 핎결하는 방법을 녌의하Ʞ위한 것읎며 명백한 것을 얞꞉하멎 ​​귞 방향윌로 진전읎 없습니닀. 따띌서 묞제 핎결을 돕고 싶거나 Ʞ여할 새로욎 정볎가 있닀멎 귞렇게하십시였. 귞렇지 않윌멎 귀하의 의견읎 마법처럌 수정 사항을 표시하지 않을 것입니닀. :)

읎것읎 LLVM의 변겜읎 필요하닀는 가정은 시Ʞ상조띌고 생각합니닀.

최소한의 성능 비용윌로 ì–žì–Žë¡œ 할 수 있닀고 생각합니닀. 귞것은 획Ʞ적읞 변화음까요 * * 귞렇습니닀. 귞러나 귞것은 할 수 있고, 읎룚얎젞알합니닀.

낮 핎결책은 unsafe 로 int 캐슀튞에 float륌 정의한 닀음 표쀀 lib에 몇 가지 도우믞 핚수륌 제공하여 Result 유형에 바읞딩 된 결곌륌 제공하는 것입니닀.

귞것은 섹시하지 않은 수정읎며 죌요 변겜 사항읎지만 궁극적윌로 몚든 개발자가 읎믞 êž°ì¡Ž UB륌 핎결하Ʞ 위핎 슀슀로 윔딩핎알하는 것입니닀. 읎것읎 올바륞 녹 방식입니닀.

@RalfJung , 읎핎하게 핎죌셔서 감사합니닀. 나는 생산적읞 람레읞 슀토밍 곌정에 누군가륌 몚욕하거나 겜멞 적윌로 개입 할 의도가 없었습니닀. 녹에 새롭닀는 것은 사싀입니닀. ë‚Žê°€ 할 수있는 음읎별로 없습니닀. 귞럌에도 불구하고 귞것은 나와 녹슬 렀하는 닀륞 사람듀에게 도움읎되며, 핎결되지 않은 결핚에 대핮 더 많읎 배우고 ꎀ렚 결곌륌낎는 데 도움읎됩니닀. 귞러나 "낮 쓞몚없는 댓Ꞁ"을 제거하는 것읎 훚씬 쉬워 질 것읎띌는 점은 읎믞 Ʞ쁩니닀.

슀레드의 앞부분에서 얞꞉했듯읎 ꎀ렚 팀읎 였래 전에 동의했듯읎 필요한 의믞 첎계륌 지원하Ʞ 위핎 llvm을 수정하여 느늬지 만 확싀히 올바륞 방법윌로 수정되고 있습니닀.

읎 토론에 더 읎상 추가 할 수있는 것은 없습니닀.

https://reviews.llvm.org/D54749

@nikic LLVM 잡의 진행읎 쀑닚 된 것 같습니닀. 가능하멎 ê°„ë‹ší•œ 업데읎튞륌 제공 할 수 있습니까? 감사.

saturating cast는 사용자가 soundess륌 얻Ʞ 위핎 사전 회귀륌 사용하렀는 겜우 선택할 수있는 띌읎람러늬 Ʞ능윌로 구현할 수 있습니까? 컎파음러의 구현을 읜고 있지만 맀우 믞묘한 것 같습니닀.

https://github.com/rust-lang/rust/blob/625451e376bb2e5283fc4741caa0a3e8a2ca4d54/src/librustc_codegen_ssa/mir/rvalue.rs#L774 -L901

우늬는 -Z 플래귞와 ꎀ계없읎 채도륌 위핎 LLVM IR을 생성하는 낎장 (현재 였픈 윔딩 된 IR 또는 향후 llvm.fpto[su]i.sat 을 녞출 할 수 있습니닀. 귞것은 전혀 얎렵지 않습니닀.

귞러나 나는 귞것읎 최선의 행동 방칚읞지 걱정됩니닀. (if?) 채도가 as 캐슀튞의 Ʞ볞 의믞가되멎 읎러한 API는 쀑복됩니닀. 또한 음시적 음지띌도 사용자가 걎전성 또는 성능을 원하는지 슀슀로 선택핎알한닀고 말하는 것도 좋지 않은 것 같습니닀.

동시에 현재 상황은 훚씬 더 나빠졌습니닀. 띌읎람러늬 API륌 추가 할 생각읎띌멎 Ʞ볞적윌로 채도륌 활성화하고 NaN에 UB가 있고 범위륌 ë²—ì–Žë‚œ 숫자가있는 unsafe 낎장 핚수륌 제공하도록 점점 더 겜고하고 있습니닀. 음반 fpto[su]i ). 귞것은 여전히 ​​Ʞ볞적윌로 동음한 선택을 제공 할 것읎지만, Ʞ볞적윌로 걎전성을 제공 할 것읎며, 새로욎 API는 믞래에 쀑복되지 않을 것입니닀.

Ʞ볞적윌로 소늬로 전환하멎 좋은 소늬가납니닀. 나는 우늬가 처음부터가 아니띌 요청에 따띌 게윌륞 낎재륌 제공 할 수 있닀고 생각합니닀. 또한 const eval은읎 겜우에도 채도륌 수행합니까? (cc @RalfJung @eddyb @ oli-obk)

CONST 평가 우늬가 읎믞 포화을하고 연령대에 귞렇게있닀가, 심지얎 믞늬 전에 생각 (나는 분명히 귞것을 변겜 êž°ì–µ 된 llvm::Constant êž°ë°˜ 평가자).

튞윗 ë‹Žì•„ 가Ʞ 묞제의 윔드에 대핮 잘 알고 있윌므로 Ʞ볞값을 전환하는 데 앞장서시겠습니까?

ë¿¡ë¿¡

채도륌 위핎 LLVM IR을 생성하는 낎장 핚수륌 녞출 할 수 있습니닀.

소슀 및 대상 유형의 각 조합에 대핮 10 개 또는 12 개의 개별 낎장 핚수가 필요할 수 있습니닀.

섌튞늎

Ʞ볞적윌로 소늬로 전환하멎 좋은 소늬가납니닀. 나는 우늬가 처음부터가 아니띌 요청에 따띌 게윌륞 낎재륌 제공 할 수 있닀고 생각합니닀.

닀륞 죌석곌 달늬 "낎재"는 as 가 포화 상태 음 때 더 적은 선행 회귀륌 갖는 것을 의믞한닀고 가정합니닀.

나는 읎것읎 알렀진 쀑요한 회귀륌 닀룚는 좋은 ì ‘ê·Œ 방식읎띌고 생각하지 않습니닀. 음부 사용자의 겜우 성능 손싀읎 싀제 묞제가 될 수 있지만 알고늬슘은 입력읎 항상 범위 낎에 있는지 확읞합니닀. 읎 슀레드에 가입하지 않은 겜우 변겜 사항읎 Stable 채널에 도달했을 때만 영향을 받는닀는 것을 알 수 있습니닀. 읎 시점에서 요청 슉시 안전하지 않은 API륌 제공하더띌도 6 ~ 12 죌 동안 멈출 수 있습니닀.

였히렀 사용 쀑닚 겜고에 대핮 읎믞 섀정된 팚턎을 따륎고 싶습니닀. 한동안 Stable에서 대안을 사용할 수있게 된 후에 만 ​​Nightly에서 전환하십시였.

소슀 및 대상 유형의 각 조합에 대핮 10 개 또는 12 개의 개별 낎장 핚수가 필요할 수 있습니닀.

좋아, 날 잡았지만 귞게 ì–Žë–€ ꎀ렚읎 있는지 몚륎겠얎? 30 개의 낎장 핚수륌 추가하는 것은 여전히 ​​사소한 음입니닀. 귞러나 싀제로는 N 씬 래퍌에서 사용하는 닚음 음반 낎장 핚수륌 사용하는 것읎 훚씬 더 쉜습니닀. " as 사욎드륌 만듀고 unsafe 캐슀튞 API 도입"옵션을 선택핎도 숫자는 변겜되지 않습니닀.

나는 읎것읎 _ 알렀진 _ 쀑요한 회귀륌 닀룚는 좋은 ì ‘ê·Œ 방식읎띌고 생각하지 않습니닀. 음부 사용자의 겜우 성능 손싀읎 싀제 묞제가 될 수 있지만 알고늬슘은 입력읎 항상 범위 낎에 있는지 확읞합니닀. 읎 슀레드에 가입하지 않은 겜우 변겜 사항읎 Stable 채널에 도달했을 때만 영향을 받는닀는 것을 알 수 있습니닀. 읎 시점에서 요청 슉시 안전하지 않은 API륌 제공하더띌도 6 ~ 12 죌 동안 멈출 수 있습니닀.

+1

몚든 늎늬슀 채널에서 겜고없는 상태륌 유지하는 것볎닀 몚든 늎늬슀 채널에서 성능 회귀없는 상태륌 유지하는 것읎 덜 쀑요핎 볎읎Ʞ 때묞에 사용 쀑닚 겜고 절찚 (교첎가 안정된 겜우 알간에만 사용 쀑닚)가 필요한지 확싀하지 않습니닀. 하지만 닀시 12 죌 더 Ʞ닀늬는 것은 Ʞ볞적윌로읎 묞제가 얌마나 였래 지속되었는지에 대한 반올늌 였류입니닀.

또한 -Zsaturating-float-casts 는 귞대로 두얎도됩니닀 (Ʞ볞값 만 변겜). 슉, 알간 사용자는 잠시 동안 계속핎서 cange에서 옵튞 아웃 할 수 있습니닀.

(예, 낎장 핚수의 수는 구현 섞부 사항 음 뿐읎며 ì–Žë–€ 것에 대한 죌장읎나 반대의 의믞가 아닙니닀.)

ë‚Žê°€ 여Ʞ에 의견을 몚두 소화 한 것윌로 죌장 할 수 없습니닀,하지만 난 LLVM읎 있닀는 읞상읎닀 @rkruppe 지ꞈ , 바로 여Ʞ UB 제거에 "최닚 겜로륌"ì°šë‹š 항목읎었닀 동결 명령을 가지고있닀?

freeze 읎 너묎 새롭Ʞ 때묞에 우늬의 LLVM 버전에서는 사용할 수 없을 수도 있습니닀. 귞래도 아마도 2020 년 상반Ʞ에 개발을 몚색핎알 할 것 같습니까?

읎 시점에서 우늬가 원하는 겜로에 대한 대략적읞 합의륌 얻Ʞ 위핎 T- 컎파음러 회의에서 토론을 위핎 지명합니닀.

freeze 은 여Ʞ에 얞꞉ 된 몚든 읎유로 여전히 묞제가 freeze 가 임의의 쓰레Ʞ 또는 비밀 킀륌 반환 할 것윌로 예상됩니닀. (얎딘가에서 옚띌읞윌로 읜었고 요앜읎 정말 마음에 듭니닀. : D)

얎욌든 묎작위 쓰레Ʞ륌 반환하는 것조찚 as 캐슀튞에는 닀소 나빠 볎입니닀. unchecked_add 와 유사하게 필요한 겜우 속도륌 위핎 더 빠륞 작업을 수행하는 것읎 합늬적읎지만 Ʞ볞값 읎 Rust의 정신에 상당히 반하는 것처럌 볎입니닀.

@SimonSapin 당신은 뚌저 반대 접귌법을 제안했습니닀 (Ʞ볞값은 불걎전 / "읎상한"의믞론읎고 명시 적윌로 걎전한 방법을 제공합니닀). 나는 당신읎 걎전성 (적절한 전환 êž°ê°„ 읎후)에 불읎행하는 것읎 합늬적읎띌고 생각하는지 또는 더 낫닀고 생각하는지 나쀑에 당신의 의견에서 말할 수 없습니닀.

ë¿¡ë¿¡

나는 LLVM읎 읎제 동결 명령을 가지고 있닀는 읞상을 받고 있는데, 읎것은 여Ʞ서 UB륌 제거하는 "최닚 겜로"륌 찚닚하는 항목읎었습니닀. 맞습니까?

몇 가지죌의 사항읎 있습니닀. 가장 쀑요한 것은 UB륌 제거하고 번듀로 제공되는 LLVM을 freeze (얞제든지 할 수 있음)을 포핚하도록 업데읎튞하더띌도 여러 읎전 버전을 지원합니닀 (닀시 LLVM 6윌로 순간) 몚든 사용자의 UB륌 싀제로 제거하렀멎 대첎 구현읎 필요합니닀.

둘짞, 묌론 "UB가 아니띌"띌는 질묞읎 우늬가 귞것에있는 동안 우늬가 ꎀ심을 갖는 전부읞지 여부입니닀. 특히 freeze(fptosi %x) 맀우 반 직ꎀ적윌로 작동한닀는 점을 닀시 강조하고 싶습니닀. 읎것은 비 결정적읎며 싀행될 때마닀 닀륞 결곌 ( @RalfJung읎 말한 것처럌 믌감한 메몚늬에서 가젞옚 결곌도)륌 반환 할 수 있습니닀. 지ꞈ 닀시 녌의하고 싶지는 않지만 채도륌 Ʞ볞값윌로 만듀고 선택되지 않은 (안전하지 않거나 freeze 사용) 변환을 만듀Ʞ 위핎 조ꞈ 더 많은 작업을 수행하렀멎 회의에서 고렀핎 볌 가치가 있습니닀. Ʞ볞값읎 아닌 옵션.

@RalfJung 낮 입장은 as 는 입력 및 출력 유형에 따띌 크게 닀륞 의믞 (잘늌, 채도, 반올늌,
)륌 가질 수 있Ʞ 때묞에읎 묞제와 ꎀ계없읎 완전히 플하는 것읎 가장 좋습니닀. 윔드륌 읜을 때 분명합니닀. (후자조찚도 foo as _ 윌로 추론 할 수 있습니닀.) 귞래서 저는 as 읎 였늘날 수행하는 겜우륌 포ꎄ하는 닀양한 명시 적윌로 명명 된 변환 방법을 제안하Ʞ위한 사전 RFC 쎈안을 가지고 있습니닀. .

낮 생각 as 귞것의 사용 왞부 될 수 있Ʞ 때묞에 확싀히, UB가 없얎알 unsafe . 쓰레Ʞ륌 반납하는 것도 좋지 않습니닀. 귞러나 우늬는 포화 캐슀튞로 읞한 성능 회귀의 알렀진 사례에 대핮 음종의 완화 / 전환 / 대안을 가젞알합니닀. 읎 전환에 대한 RFC 쎈안을 찚닚하지 ì•Šêž° 위핎 포화 캐슀튞의 띌읎람러늬 구현에 대핎서만 질묞했습니닀.

ë¿¡ 빵뀚

낮 입장은읎 묞제에 ꎀ계없읎 완전히 플하는 것읎 가장 좋습니닀. 왜냐하멎 귞것은 맀우 닀륞 의믞 (절닚, 포화, 반올늌,
)륌 가질 수 있Ʞ 때묞입니닀.

동의합니닀. 귞러나 귞것은읎 묞제륌 핎결하는 데 싀제로 도움읎되지 않습니닀.

(또한, as 을 (륌) 필요로하지 않게 만듀Ʞ 위핎 녞력하고있얎 Ʞ쁩니닀. Ʞ대합니닀. : D)

안전하지 않은 왞부에서 사용할 수 있Ʞ 때묞에 UB가 없얎알한닀고 생각합니닀. 쓰레Ʞ륌 반납하는 것도 좋지 않습니닀. 귞러나 우늬는 포화 캐슀튞로 읞한 성능 회귀의 알렀진 사례에 대핮 음종의 완화 / 전환 / 대안을 가젞알합니닀. 읎 전환에 대한 RFC 쎈안을 찚닚하지 ì•Šêž° 위핎 포화 캐슀튞의 띌읎람러늬 구현에 대핎서만 질묞했습니닀.

귞래서 우늬는 최종 상태가 float-to-int as 포화 상태 여알한닀는 데 동의하는 것 같습니닀. 나는 귞것읎 우늬가 향하고있는 최종 목표 읞 한 ì–Žë–€ 전환 계획에 만족합니닀.

ê·ž 최종 목표는 나에게 좋은 것 같습니닀.

나는 읎것읎 _ 알렀진 _ 쀑요한 회귀륌 닀룚는 좋은 ì ‘ê·Œ 방식읎띌고 생각하지 않습니닀. 음부 사용자의 겜우 성능 손싀읎 싀제 묞제가 될 수 있지만 알고늬슘은 입력읎 항상 범위 낎에 있는지 확읞합니닀. 읎 슀레드에 가입하지 않은 겜우 변겜 사항읎 Stable 채널에 도달했을 때만 영향을 받는닀는 것을 알 수 있습니닀. 읎 시점에서 요청 슉시 안전하지 않은 API륌 제공하더띌도 6 ~ 12 죌 동안 멈출 수 있습니닀.

낮 생각에, 핎당 사용자가 6-12 죌 동안 rustc 업귞레읎드륌 Ʞ닀늬멎 섞상의 종말읎 아닐 것입니닀. 두 겜우 몚두 닀가였는 늎늬슀에서 아묎것도 필요하지 않거나 띌읎람러늬에 MSRV 제앜읎있을 수 있습니닀. 받치닀.

한펾, 슀레드에 가입하지 않은 사용자는 성능 손싀읎 발생할 수있는 것처럌 잘못 컎파음 될 수 있습니닀. 묎엇을 우선시핎알합니까? 우늬는 안정성에 대한 볎슝을 제공하고 안전에 대한 볎슝을 제공합니닀.하지만 제가 아는 한 성능에 대핎서는 귞러한 볎슝읎 제공되지 않습니닀 (예 : RFC 1122는 성능을 전혀 얞꞉하지 않음).

였히렀 사용 쀑닚 겜고에 대핮 읎믞 섀정된 팚턎을 따륎고 싶습니닀. 한동안 Stable에서 대안을 사용할 수있게 된 후에 만 ​​Nightly에서 전환하십시였.

지원 쀑닚 겜고의 겜우 안정적읞 대안읎있을 때까지 지원 쀑닚을 Ʞ닀늬는 결곌는 적얎도 ë‚Žê°€ 아는 한 대Ʞ êž°ê°„ 동안 걎전성 구멍읎 발생하지 않습니닀. (또한 여Ʞ에 낎장 핚수륌 제공 할 수 있지만 음반적읞 겜우 걎전성 구멍을 ê³ ì¹  때 합늬적윌로 대안을 제공하지 못할 수 있습니닀. 따띌서 안정적읞 대안을 갖는 것읎 얎렀욎 요구 사항읎 될 수 있닀고 생각하지 않습니닀.)

좋아, 날 잡았지만 귞게 ì–Žë–€ ꎀ렚읎 있는지 몚륎겠얎? 30 개의 낎장 핚수륌 추가하는 것은 여전히 ​​사소한 음입니닀. 귞러나 싀제로는 N 씬 래퍌에서 사용하는 닚음 음반 낎장 핚수륌 사용하는 것읎 훚씬 더 쉜습니닀. " as 사욎드륌 만듀고 unsafe 캐슀튞 API 도입"옵션을 선택핎도 숫자는 변겜되지 않습니닀.

닚음 제넀늭 낎장 핚수는 12/30 특정 몚녞 몚픜 읞슀턎슀화륌 위핎 컎파음러에서 별도의 구현을 요구하지 않습니까?

LLVM읎 읎믞 대부분의 작업을 수행했Ʞ 때묞에 컎파음러에 낎장 핚수륌 추가하는 것은 사소 할 수 있지만 전첎 비용곌는 거늬가 멀습니닀. 또한 Miri, Cranelift의 구현 및 사양에 필요한 최종 작업읎 있습니닀. 귞래서 누군가가 필요로하는 Ʞ회에 낎장 Ʞ능을 추가핎서는 안된닀고 생각합니닀.

귞러나 나는 더 많은 낎재륌 녞출하는 것을 반대하지는 않지만 누군가 귞것을 필요로하는 겜우 제안 (예 : 정교한 섀명읎있는 PR)을 만듀고 벀치마킹 수치 등윌로 추가륌 정당화핎알합니닀.

또한 -Zsaturating-float-casts 는 귞대로 두얎도됩니닀 (Ʞ볞값 만 변겜). 슉, 알간 사용자는 잠시 동안 계속핎서 cange에서 옵튞 아웃 할 수 있습니닀.

읎것은 나에게 ꎜ찮아 볎읎지만 읎믞읎 플래귞륌 사용하는 사람듀을 위핎 의믞륌 불걎전하게 변겜하지 않도록 플래귞 읎늄을 -Zunsaturating-float-casts 로 변겜하는 것읎 좋습니닀.

섌튞늎

닚음 제넀늭 낎장 핚수는 12/30 특정 몚녞 몚픜 읞슀턎슀화륌 위핎 컎파음러에서 별도의 구현을 요구하지 않습니까?

아니요, 대부분의 구현은 소슀 및 대상 비튞 폭에 대한 맀개 변수화륌 통핎 읎믞 공유 될 수 있윌며 읎믞 공유됩니닀. 몇 비튞 만 대소 묞자 구분읎 필요합니닀. miri의 구현에도 동음하게 적용되며 닀륞 구현 및 사양에도 적용됩니닀.

(펞집 : 명확하게 말하멎,읎 공유는 N 개의 고유 한 낎장 핚수가있는 겜우에도 발생할 수 있지만 닚음 음반 낎장 핚수는 낎장 핚수별로 필요한 상용구륌 쀄입니닀.)

귞래서 누군가가 필요로하는 Ʞ회에 낎장 Ʞ능을 추가핎서는 안된닀고 생각합니닀.

귞러나 나는 더 많은 낎재륌 녞출하는 것을 반대하지는 않지만 누군가 귞것을 필요로하는 겜우 제안 (예 : 정교한 섀명읎있는 PR)을 만듀고 벀치마킹 수치 등윌로 추가륌 정당화핎알합니닀. 귞동안 걎전성 구멍을 고치는 것을 막아알한닀고 생각하지 않습니닀.

읎믞 벀치마킹 수치가 있습니닀. 였래 전 벀치 마크 요청을 통핎 JPEG 읞윔딩읎 포화 캐슀튞륌 사용 상당히 느렀진닀 는 것을 알고 있습니닀. 누군가 닀시 싀행할 수 있지만 읎것읎 변겜되지 않았닀고 확신하고 (묌론 특정 숫자가 동음하지는 않지만) 채도가 구현되는 방식에 대한 향후 변겜 (예 : 읞띌읞 asm 또는 @nikic읎 작업 한 LLVM 낎장 핚수)는 귌볞적윌로읎륌 바꿀 것입니닀. 믞래에 대핮 확신하Ʞ는 얎렵지만, 제가 추잡 한 바에 따륎멎 성능을 되 찟을 수있는 유음한 방법은 unsafe 변환 또는 freeze 사용하는 것곌 같읎 범위 검사없읎 윔드륌 생성하는 것을 사용하는 것입니닀.

좋습니닀. êž°ì¡Ž 벀치마킹 수치륌 볎멎 핎당 낎장 핚수에 대한 적극적읞 욕구가있는 것 같습니닀. 귞렇닀멎 닀음곌 같은 싀행 계획을 제안합니닀.

  1. 동시에 :

    • #[unstable(...)] 핚수륌 통핎 알간에 녞출되는 낎장 핚수륌 소개합니닀.

    • -Zsaturating-float-casts 제거하고 -Zunsaturating-float-casts 합니닀.

    • Ʞ볞값을 -Zsaturating-float-casts 전환합니닀.

  2. 잠시 후 낎장 핚수륌 안정화합니닀. 우늬는 조ꞈ 빚늬 추적 할 수 있습니닀.
  3. 잠시 후 -Zunsaturating-float-casts 제거하십시였.

좋아. 낎장 핚수가 음부 공용 API의 구현 섞부 사항읎띌는 점을 제왞하멎 f32 및 f64 메소드 음 수 있습니닀. 닀음 쀑 하나 음 수 있습니닀.

  • 선택적윌로 전죌곡에서 음반 특성의 메서드 (변환의 정수 반환 유형에 대한 맀개 변수 포핚)
  • 닀양한 반환 유형을 지원하Ʞ 위핎 지원 튞레읎 튾 ( str::parse 및 FromStr 와 유사)가있는 고유 메서드
  • 읎늄에 대상 유형읎있는 여러 비 음반 고유 메서드

ë„€, 방법읎나 귞와 같은 것을 통핎 낎장 핚수륌 녞출하는 것을 의믞했습니닀.

읎늄에 대상 유형읎있는 여러 비 음반 고유 메서드

읎것은 우늬가하는 음반적읞 음처럌 느껎집니닀.읎 옵션에 대한 읎의가 있습니까?

귞래도? 메소드 읎늄의 음부로 유형 (서명)의 읎늄읎있을 때 임시 "하나의"변환 (예 Vec::as_slice 및 [T]::to_vec ) 또는 찚읎가 유형읎 아닌 음렚의 전환 (예 to_ne_bytes , to_be_bytes , to_le_bytes ). 귞러나 std::convert 의 특성에 대한 동Ʞ의 음부는 u8::to_u16 , u8::to_u32 , u8::to_u64 등곌 같은 수십 개의 개별 메서드륌 플하는 것읎 었습니닀.

낮 궁ꞈ한 점은 메서드가 unsafe fn 여알한닀는 점을 감안할 때 읎것읎 자연적윌로 특성에 음반화 될 수 있는지 여부입니닀. 고유 한 메서드륌 추가하멎 항상 튞레읎 튾 구현에있는 메서드에 위임 할 수 있습니닀.

안전하지 않은 변환에 대한 특성을 추가하는 것읎 읎상핎 볎읎지만 아마도 Simon은 부동 소수점곌 정수 유형의 각 조합에 대핮 닀륞 방법읎 필요할 수 있닀는 사싀에 대핮 생각하고있을 것입니닀 (예 : f32::to_u8_unsaturated , f32::to_u16_unsaturated 등).

ꞎ 싀에 얜맀읎지 ì•Šêž° 위핎 나는 완전히 묎지하게 읜지 않았지만 귞것읎 바람직하거나 u32 또는 닀륞 것윌로 변환되는 f32::to_integer_unsaturated 륌 갖는 것윌로 충분합니까? 안전하지 않은 변환의 대상 유형에 대한 분명한 선택읎 있습니까?

안전하지 않은 변환을 i32 / u32 (예륌 듀얎)로만 제공하멎 값 범위가 엄격하게 작지 않은 몚든 정수 유형읎 완전히 제왞되며, 읎는 반드시 필요한 겜우가 있습니닀. 더 작은 크Ʞ (JPEG 읞윔딩에서와 같읎 u8까지)도 종종 필요하지만 더 넓은 정수 유형윌로 변환하고 as (음반적윌로 묎료는 아니지만 저렎핚)로 잘띌서 에뮬레읎션 할 수 있습니닀.

귞러나 우늬는 가장 큰 정수 크Ʞ로의 변환만을 제공 할 수 없습니닀. 귞것듀은 항상 Ʞ볞적윌로 지원되는 것은 아니며 (따띌서 느늬게) 최적화로 í•Žê²°í•  수 없습니닀. 후자는 UB (LLVM IR에서)륌 가지고 있Ʞ 때묞에 "큰 정수로 변환 한 닀음 자륎Ʞ"륌 "작은 정수로 직접 변환"윌로 최적화하는 것은 옳지 않습니닀. / 잘띌낌 때 원래 변환 결곌가 래핑 된 겜우 닀륞 결곌 (Ʞ계 윔드 수쀀, 대부분의 아킀텍처).

싀용적윌로 128 비튞 정수륌 제왞하고 64 비튞 정수에 쎈점을 맞추더띌도 음반적읞 32 비튞 대상에는 여전히 좋지 않습니닀.

나는읎 대화에 익숙하지 않지만 프로귞래밍에는 익숙하지 않습니닀. 사람듀읎 포화 변환곌 NaN을 0윌로 변환하는 것읎 합늬적읞 Ʞ볞 동작읎띌고 생각하는 읎유가 궁ꞈ합니닀. Java가읎 작업을 수행한닀는 것을 읎핎합니닀 (랩핑읎 훚씬 더 음반적윌로 볎읎지만), NaN읎 싀제로 올바륞 변환읎띌고 말할 수있는 정수 값은 없습니닀. 마찬가지로 예륌 듀얎 1000000.0을 65535 (u16)로 변환하는 것은 잘못된 것 같습니닀. 분명히 정답 읞 u16은 없습니닀. 적얎도 C / C ++, C #, go 및 Ʞ타와 공유되는 동작 읞 16960윌로 변환하는 현재 동작볎닀 낫닀고 생각하지 않습니닀. 따띌서 적얎도 닀소 놀랍지 않습니닀.

였버플로 검사와의 유사성에 대핮 여러 사람읎 얞꞉ 한 바 있윌며 읎에 동의합니닀. 또한 정수륌 0윌로 나누는 것곌 유사합니닀. 잘못된 변환은 잘못된 산술처럌 당황핎알한닀고 생각합니닀. NaN-> 0 및 1000000.0-> 65535 (또는 16960)에 의졎하는 것은 정수 였버플로 또는 가상의 n / 0 == 0에 의졎하는 것만 큌 였류가 발생하Ʞ 쉬욎 것처럌 볎입니닀. Ʞ볞적윌로 였류륌 생성핎알하는 종류입니닀. (늎늬슀 빌드에서 rust는 정수 산술곌 마찬가지로 였류 검사륌 제거 할 수 있습니닀.) 귞늬고 드묌게 NaN을 0윌로 변환하거나 부동 소수점 포화륌 갖Ʞ륌 _ 원하는 겜우에는 닀음곌 같읎 선택핎알합니닀. 정수 였버플로륌 선택핎알합니닀.

성능에 ꎀ핎서는 음반 변환을 수행하고 하드웚얎 결핚에 의졎하는 것읎 가장 높은 음반 성능을 제공하는 것 같습니닀. 예륌 듀얎 x86곌 ARM 몚두 부동 소수점에서 정수로의 변환을 올바륎게 표현할 수없는 겜우 (NaN 및 범위륌 ë²—ì–Žë‚œ 겜우 몚두 포핚) 하드웚얎 예왞륌 발생시킵니닀. 읎 솔룚션은 디버귞 빌드에서 부동 소수점에서 작은 정수 유형윌로 직접 변환하는 겜우륌 제왞하고는 유횚하지 않은 변환을 제왞하고 비용읎 듀지 않습니닀. 드묞 겜우읎지만 여전히 비교적 저렎핎알합니닀. (읎러한 예왞륌 지원하지 않는 읎론적 읞 하드웚얎에서는 소프튞웚얎에서 에뮬레읎션 할 수 있지만 닀시 디버귞 빌드에서만 가능합니닀.) 하드웚얎 예왞는 정확히 0윌로 정수 나누Ʞ륌 감지하는 것읎 였늘날 구현되는 방식읎띌고 생각합니닀. LLVM에 대한 많은 읎알Ʞ륌 볎았윌므로 여Ʞ에 제한읎있을 수 있지만 볞질적윌로 잘못된 변환에 대핮 몚혞한 대첎 동작을 제공하Ʞ 위핎 늎늬슀 빌드에서도 몚든 부동 소수점 변환에서 소프튞웚얎 에뮬레읎션을 사용하는 것은 불행한 음입니닀.

@admilazz 우늬는 LLVM읎 할 수있는 음에 제앜을 받고 있윌며 현재 LLVM은 정의되지 않은 동작의 위험없읎 싀수륌 정수로 횚윚적윌로 변환하는 방법을 녞출하지 않습니닀.

포화 상태는 ì–žì–Žê°€ as 캐슀튞륌 항상 성공하도록 정의하Ʞ 때묞에 연산자륌 대신 팹닉 상태로 변겜할 수 없Ʞ 때묞입니닀.

마찬가지로 예륌 듀얎 1000000.0을 65535 (u16)로 변환하는 것은 잘못된 것 같습니닀. 분명히 정답 읞 u16은 없습니닀. 적얎도 나는 귞것을 16960윌로 변환하는 현재 동작볎닀 더 나은 것윌로 볎지 않습니닀.

귞것은 나에게 분명하지 않았Ʞ 때묞에 지적 할 가치가 있닀고 생각합니닀. 16960은 1000000.0을 충분한 폭의 정수로 변환 한 닀음 16 개의 하위 비튞륌 유지하Ʞ 위핎 자륞 결곌입니닀.

읎것은 ~읎 슀레드에서 읎전에 제안 된 옵션읎 아니며 ~ (펞집 : 여Ʞ에서 잘못되었습니닀. 찟지 못핎 죄송합니닀) 현재 동작도 아닙니닀. Rust의 현재 동작은 범위륌 ë²—ì–Žë‚œ float-to-integer 변환읎 Undefined Behavior띌는 것입니닀. 싀제로 읎것은 종종 가비지 값윌로 읎얎지며 원칙적윌로 잘못 컎파음 및 췚앜성을 유발할 수 있습니닀. 읎 슀레드는 몚든 것을 고치는 것입니닀. Rust 1.39.0에서 아래 프로귞랚을 싀행하멎 맀번 닀륞 값을 얻습니닀.

fn main() {
    dbg!(1000000.0 as u16);
}

놀읎터 . 출력 예 :

[src/main.rs:2] 1000000.0 as u16 = 49072

개읞적윌로 정수형 잘늌읎 채도볎닀 낫거나 나쁘지 않닀고 생각합니닀. 둘 ë‹€ 범위륌 ë²—ì–Žë‚œ 값에 대핮 수치 적윌로 잘못되었습니닀. UB가 아니띌 결정 론적읎띌멎 였류없는 변환읎 ê·ž 자늬륌 찚지합니닀. 알고늬슘을 통핎 값읎 범위 낎에 있음을 읎믞 알고 있거나 귞러한 겜우에 대핮 신겜 쓰지 않을 수 있습니닀.

Result 륌 반환하는 잘못된 변환 API 도 추가핎알한닀고 생각하지만 여전히 RFC 쎈안 작성을 완료핎알합니닀. :)

"수학적 정수로 변환 한 닀음 대상 너비로 자륎Ʞ"또는 "랩 얎띌욎드"시맚틱 은 읎 슀레드에서 읎전에 제안되었습니닀 (https://github.com/rust-lang/rust/issues/10184#issuecomment-299229143). 나는 특히 귞것을 좋아하지 않는닀 :

  • 채도볎닀 앜간 덜 현명하닀고 생각합니닀. 채도는 음반적윌로 범위륌 ë²—ì–Žë‚œ 숫자에 대핮 합늬적읞 결곌륌 제공하지 않지만 닀음곌 같습니닀.

    • 숫자가 범위륌 앜간 ë²—ì–Žë‚  때 (예 : 누적 된 반올늌 였류로 읞핎) 랩 얎띌욎드볎닀 더 현명하게 작동합니닀. 반대로, 둘러싞는 캐슀튞는 float 계산에서 앜간의 반올늌 였류륌 정수 영역에서 가능한 최대 였류로 슝폭 할 수 있습니닀.

    • 디지턞 신혞 처늬에서 닀소 음반적윌로 사용되므로 싀제로 원하는 응용 프로귞랚읎 적얎도 있습니닀. 대조적윌로, 나는 랩 얎띌욎드 시맚틱윌로부터 읎득을 얻는 닚음 알고늬슘을 몚륞닀.

  • AFAIK는 랩 얎띌욎드 의믞론을 선혞 하는 유음한 읎유는 소프튞웚얎 에뮬레읎션의 횚윚성읎지만, 읎것은 슝명되지 않은 가정처럌 볎입니닀. 나는 틀렞닀는 것읎 슝명되얎 Ʞ쁠 것읎지만, 간략하게 삎펎볎멎 ALU 명령의 ꞎ 첎읞 (묎한곌 NaN을 개별적윌로 처늬하Ʞ위한 분Ʞ 포핚)읎 필요한 것처럌 볎읎므로 분명한 것읎 더 낫닀고 생각하지 않습니닀. 닀륞 것볎닀 성능.
  • NaN 대핮 묎엇을핎알하는지에 대한 질묞은 정수로의 변환에 대한 추악한 묞제읎지만, 채도는 적얎도 묎한대에 대핮 특별한 대 / 소묞자륌 필요로하지 않습니닀 (의믞론읎나 대부분의 구현에서). 귞러나 랩 얎띌욎드의 겜우 +/- 묎한대에 핎당하는 정수는 묎엇입니까? JavaScript는 귞것읎 0읎띌고 말하고, NaN에서 as 팚닉을 만듀멎 묎한대에서도 팹닉 할 수 있닀고 가정합니닀. 귞러나 얎느 쪜읎든 정상 및 비정규 숫자륌 볎는 것볎닀 빠륎게 랩 얎띌욎드륌 만드는 것읎 더 얎렀워 볎입니닀. 혌자서 제안 할 것입니닀.

변환을위한 포화 의믞론에 의핎 회귀 된 대부분의 윔드는 SIMD륌 사용하는 것읎 더 나을 것읎띌고 생각합니닀. 따띌서 안타깝게도읎 변겜윌로 읞핎 고성능 윔드가 작성되는 것을 막을 수 없윌며 (특히 닀륞 의믞 첎계륌 가진 낎장 핚수가 제공되는 겜우) 음부 프로젝튞륌 더 빠륞 (읎동성읎 떚얎지는 겜우) 구현윌로 읎동시킬 수도 있습니닀.

귞렇닀멎 걎전성 구멍을 막는 것을 방지하Ʞ 위핎 앜간의 성능 회귀륌 정당화핎서는 안됩니닀.

https://github.com/rust-lang/rust/pull/66841 은 값읎 알렀진 겜우 LLVM의 fptoui 및 fptosi 로 변환하는 unsafe fn 메서드륌 추가합니닀. 범위 낎에 있고 포화 상태가되는 것은 ìž¡ì • 가능한 성능 회귀입니닀.

ê·ž 후 나는 as 의 Ʞ볞값을 바꟞는 것읎 좋닀고 생각합니닀 (귞늬고 아마도 닀륞 -Z 플래귞륌 추가하여 옵튞 아웃 할 수 있습니까?). 비록 귞것은 아마도 공식적읞 Lang 팀 결정음 것입니닀.

ê·ž 후 나는 as 의 Ʞ볞값을 바꟞는 것읎 좋닀고 생각합니닀 (귞늬고 아마도 닀륞 -Z 플래귞륌 추가하여 옵튞 아웃 할 수 있습니까?). 비록 귞것읎 공식적읞 Lang 팀 결정음 것입니닀.

귞래서 우늬는 (적얎도 거Ʞ에 있었던 사람듀곌 핚께 ì–žì–Ž 팀) 읎것을 https://github.com/rust-lang/lang-team/blob/master/minutes/2019-11-21.md 에서 녌의했고 우늬는 생각했습니닀 새로욎 낎장 핚수륌 추가하고 -Zunsaturated-float-casts 륌 추가하는 것읎 좋은 첫 번짞 닚계입니닀.

필요한 겜우 FCP륌 사용하여 Ʞ볞값을 ê·ž 음부로 또는 ê·ž 직후에 전환하는 것읎 좋을 것읎띌고 생각합니닀.

새로욎 낎장 핚수에 의핎 https://github.com/rust-lang/rust/pull/66841 곌 같은 것을 의믞한닀고 가정합니닀.

Ʞ볞값을 변겜하지 않고 -Z unsaturated-float-casts 을 추가한닀는 것은 묎엇을 의믞합니까? "였류 : 알 수없는 디버깅 옵션"을 표시하지 않고 no-op윌로 수띜 하시겠습니까?

새로욎 낎장 핚수에 의핎 닀음곌 같은 의믞가 있닀고 가정합니닀. # 66841

ë„€ 👍-선두에 서서 감사합니닀.

Ʞ볞값을 변겜하지 않고 -Z unsaturated-float-casts 을 추가한닀는 것은 묎엇을 의믞합니까? "였류 : 알 수없는 디버깅 옵션"을 표시하지 않고 no-op윌로 수띜 하시겠습니까?

ë„€ Ʞ볞적윌로. 또는 -Z saturated-float-casts 대신 -Z unsaturated-float-casts 하고 Ʞ볞값을 직접 전환하지만 더 적은 수의 PR에 대핮 동음한 결곌로 읎얎젞알합니닀.

나는 "불포화"제안을 정말로 읎핎하지 못한닀. 목표가 새로욎 Ʞ볞값을 옵튞 아웃 할 수있는 녞람륌 제공하는 것읎띌멎 êž°ì¡Ž 플래귞의 Ʞ볞값을 변겜하고 더 읎상 아묎것도하지 않는 것읎 더 쉜습니닀. 목표가 튞레읎드 였프 (불걎전 핹)에 대핮 더 명확한 새 읎늄을 선택하는 것읎띌멎 "불포화"는 끔찍합니닀. 대신 "안전하지 않은"또는 "UB"또는 읎와 유사한 읎늄을 포핚하는 읎늄을 제안합니닀. 묎서욎 ë‹šì–Ž (예 -Z fix-float-cast-ub .

unchecked 는 API 읎늄에 선례가있는 용얎입니닀.

@admilazz 우늬는 LLVM읎 할 수있는 음에 제앜을 받고 있윌며 현재 LLVM은 정의되지 않은 동작의 위험없읎 싀수륌 정수로 횚윚적윌로 변환하는 방법을 녞출하지 않습니닀.

귞러나 아마도 정수 였버플로와 마찬가지로 디버귞 빌드에서만 런타임 검사륌 추가 할 수 있습니닀.

AFAIK는 랩 얎띌욎드 의믞론을 선혞하는 유음한 읎유는 소프튞웚얎 에뮬레읎션의 횚윚성입니닀.

둘 ë‹€ 틀 ë žêž° 때묞에 wraparound 또는 saturation을 선혞하지 않는닀고 생각하지만 wraparound는 C / C ++, C #, go, 아마도 D, 귞늬고 확싀하게 rust와 비슷한 많은 얞얎에서 사용되는 방법읎띌는 읎점읎 있습니닀. 더 많은 것, 귞늬고 녹의 현재 행동 (적얎도 때때로)읎Ʞ도합니닀. 슉, 정수 였버플로와 0윌로 나누Ʞ와 같은 유횚하지 않은 산술에 대핮 수행하는 것처럌 "잘못된 변환에 대한 팹닉 (아마도 디버귞 빌드에서만)"읎 읎상적읎띌고 생각합니닀.

(흥믞롭게도 놀읎터 에서 16960을 얻었습니닀. 귞러나 게시 된 닀륞 예에서 녹읎 닀륎게 작동한닀는 것을 알 수 있습니닀 ...)

포화 상태는 ì–žì–Žê°€ 항상 성공하Ʞ 위핎 캐슀튞로 정의하Ʞ 때묞에 연산자륌 대신 팹닉 상태로 변겜할 수 없Ʞ 때묞입니닀.

우늬가 읎믞읎 작업을 수행 한 사람듀의 결곌에 ꎀ심읎있는 한 작업의 평가 대상을 변겜하는 것은 읎믞 큰 변화입니닀. 읎처럌 당황하지 않는 행동도 바뀔 수 있습니닀.

NaN에서 팚닉윌로 만듀멎 묎한대에서도 팹닉 할 수 있닀고 생각합니닀. 귞러나 얎느 쪜읎든 빠륎게 만듀Ʞ가 더 얎렀워 질 것 같습니닀.

정수 였버플로가 귞렇듯읎 디버귞 빌드에서만 확읞하멎 두 가지 장점을 몚두 얻을 수 있닀고 생각합니닀. 변환읎 정확하닀는 것읎 볎장되고 (디버귞 빌드에서) 사용자 였류가 잡힐 가능성읎 더 높윌며 옵튞 읞 할 수 있습니닀. 랩 얎띌욎드 및 / 또는 원하는 겜우 채도와 같은 읎상한 동작에 대한 성능은 가능한 한 좋습니닀.

또한 명령 쀄 슀위치륌 통핎읎 항목을 제얎하는 ​​것읎 읎상핎 볎입니닀. 귞것은 큰 망치입니닀. 확싀히 범위륌 ë²—ì–Žë‚œ 변환의 원하는 동작은 알고늬슘의 특성에 따띌 달띌 지므로 변환 닚위로 제얎핎알합니닀. f.to_u16_sat () 및 f.to_u16_wrap () 또는 읎와 유사한 옵튞 읞을 제안하고 윔드의 의믞륌 변겜하는 명령 쀄 옵션읎 없습니닀. 귞것은 서로 닀륞 윔드 조각을 혌합하고 음치시킀는 것을 얎렵게 만듀고 귞것을 읜는 것윌로 묎엇을하는지 읎핎할 수 없습니닀 ...

귞늬고 "유횚하지 않은 겜우 팹닉"을 Ʞ볞 동작윌로 만드는 것읎 진정윌로 용납되지 않는 겜우읎륌 구현하지만 디버귞 빌드에서 유횚성 검사 만 수행하는 낎장 메서드륌 사용하여 (vast 대부분?) 변환 후 동음한 수륌 얻을 것윌로 예상되지만 늎늬슀 빌드에서 페널티륌 지불하지 않는 겜우.

흥믞롭게도 놀읎터에서 16960을 얻었습니닀.

읎것읎 Undefined Behavior가 작동하는 방식입니닀. 프로귞랚의 정확한 공식화와 정확한 컎파음러 버전 및 정확한 컎파음 플래귞에 따띌 결정적 동작읎나 맀 싀행마닀 변겜되는 가비지 값 또는 잘못된 컎파음읎 발생할 수 있습니닀. 컎파음러는 묎엇읎든 할 수 있습니닀.

랩 얎띌욎드는 C / C ++, C #, go, 아마도 D 등의 여러 얞얎에서 사용되는 방법읎띌는 장점읎 있습니닀.

정말읞가요? 적얎도 C와 C ++에서는 아니지만 Rust와 같은 Undefined Behavior륌 가지고 있습니닀. 읎것은 우연읎 아닙니닀. 우늬는 죌로 C와 C ++륌 구현하는 clang을 위핎 구축 된 LLVM을 사용합니닀. C #에 대핮 확신하고 가십니까?

C11 표쀀 https://port70.net/~nsz/c/c11/n1570.html#6.3.1.4

싀수 부동 형의 유한 값읎 _Bool읎 아닌 정수형윌로 변환되멎 소수 부분읎 삭제됩니닀 (슉, 값읎 0윌로 잘늌). 정수 부분의 값을 정수 유형윌로 표시 할 수없는 겜우 동작읎 정의되지 않습니닀.

정수형의 값읎 부혞없는 유형윌로 변환 될 때 수행되는 나뚞지 연산은 싀수 부동 형의 값읎 부혞없는 유형윌로 변환 될 때 수행 할 필요가 없습니닀. 따띌서 읎식 가능한 싀제 부동 값의 범위는 (-1, Utype_MAX + 1)입니닀.

C ++ 17 표쀀 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#section.7.10

부동 소수점 유형의 prvalue는 정수 유형의 prvalue로 변환 될 수 있습니닀. 변환읎 잘늜니닀. 슉, 소수 부분읎 삭제됩니닀. 잘늰 값을 대상 유형윌로 표시 할 수없는 겜우 동작읎 정의되지 않습니닀.

C # ì°žì¡° https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions

double 또는 float 값을 정수 유형윌로 변환하멎읎 값은 가장 가까욎 정수 값윌로 0윌로 반올늌됩니닀. 결곌 정수 값읎 대상 유형의 범위륌 벗얎나멎 결곌는 였버플로 검사 컚텍슀튞에 따띌 달띌집니닀. 확읞 된 컚텍슀튞에서는 OverflowException읎 throw되고 확읞되지 않은 컚텍슀튞에서는 결곌가 대상 유형의 지정되지 않은 값입니닀.

따띌서 UB가 아니띌 "지정되지 않은 값"음뿐입니닀.

@admilazz 읎것곌 정수 였버플로 사읎에는 큰 찚읎가 있습니닀. 정수 였버플로는 바람직하지 않지만 잘 정의되얎 있습니닀. 부동 소수점 형변환은 정의되지 않은 동작 입니닀.

당신읎 요구하는 것은 늎늬슀 몚드에서 Vec 겜계 검사륌 끄는 것곌 비슷하지만 정의되지 않은 동작을 허용하Ʞ 때묞에 잘못된 것입니닀.

안전 윔드에서 정의되지 않은 동작을 허용하는 것은 늎늬슀 몚드에서만 발생하더띌도 허용되지 않습니닀. 따띌서 수정 사항은 늎늬슀 및 디버귞 몚드 몚두에 적용되얎알합니닀.

묌론 디버귞 몚드에서 더 제한적읞 수정을 할 수 있지만 늎늬슀 몚드에 대한 수정은 여전히 ​​잘 정의되얎 있얎알합니닀.

@admilazz 읎것곌 정수 였버플로 사읎에는 큰 찚읎가 있습니닀. 정수 였버플로는 바람직하지 않지만 잘 정의되얎 있습니닀. 부동 소수점 캐슀튞는 정의되지 않은 동작입니닀.

묌론입니닀.하지만읎 슀레드는 동작을 정의하는 것입니닀. Amanieu가 위에서 유용하게 ì°žì¡°í•œ C # 사양에서와 같읎 "대상 유형의 지정되지 않은 값"을 생성하는 것윌로 정의 된 겜우 더 읎상 정의되지 않을 것입니닀 (위험한 방식윌로). 디버귞 빌드에서 여전히 팹닉 상태가되Ʞ 때묞에 싀제 프로귞랚에서 정수 였버플로의 잘 정의 된 특성을 쉜게 사용할 수 없습니닀. 마찬가지로, 늎늬슀 빌드에서 유횚하지 않은 캐슀튞에 의핎 생성 된 값은 예잡 가능하거나 특히 유용 할 필요가 없습니닀. 디버귞 빌드에서 팚닉읎 발생하멎 프로귞랚읎 싀제로 사용할 수 없Ʞ 때묞입니닀. 읎것은 싀제로 최적화륌 위핎 컎파음러에 최대 범위륌 제공하는 반멎, 포화와 같은 동작을 선택하멎 컎파음러가 제한되고 넀읎티람 포화 변환 명령읎없는 하드웚얎에서 상당히 느렀질 수 있습니닀. (귞늬고 채도가 명확하게 정확하지 않습니닀.)

당신읎 요구하는 것은 늎늬슀 몚드에서 Vec 겜계 검사륌 끄는 것곌 유사하지만 정의되지 않은 동작을 허용하Ʞ 때묞에 잘못된 것입니닀. 안전한 윔드에서 정의되지 않은 동작을 허용하는 것은 허용되지 않습니닀.

정의되지 않은 몚든 동작읎 동음하지는 않습니닀. 정의되지 않은 동작은 묎슚 음읎 음얎나는지 결정하는 것은 컎파음러 구현 자에게 달렀 있음을 의믞합니닀. float륌 int로 캐슀팅하여 rust의 안전 볎장을 위반할 방법읎없는 한, 사람듀읎 임의의 메몚늬 위치에 ì“ž 수 있도록 허용하는 것곌 유사하지 않닀고 생각합니닀. 귞럌에도 불구하고 묌론 나는 귞것읎 반드시 예잡 가능하지는 않더띌도 안전을 볎장한닀는 의믞로 정의되얎알한닀는 데 동의합니닀.

정말읞가요? 적얎도 C와 C ++는 아니지만 Rust와 같은 Undefined Behavior륌 가지고 있습니닀 ... C #에 대핮 확신하고 가섞요?

귞럎 수 있지. 나는 귞듀의 몚든 사양을 읜지 않았습니닀. 방ꞈ 닀양한 컎파음러륌 테슀튞했습니닀. "ë‚Žê°€ 시도한 몚든 컎파음러가 읎런 식윌로 수행한닀"는 말은 "ì–žì–Ž 사양읎읎륌 읎렇게 정의한닀"는 말곌 닀륎닀는 말읎 맞습니닀. 귞러나 나는 얎욌든 였버플로륌 찬성하는 것읎 아니띌 귞것읎 가장 흔한 것 같닀는 것을 지적 할 뿐읎닀. 저는 1) 정수 였버플로로부터 볎혞하는 것곌 같은 읎유로 1000000.0읎 65535 또는 16960읎되는 것곌 같은 "잘못된"결곌로부터 볎혞하는 변환에 찬성하고 있습니닀. 버귞 음 가능성읎 높윌므로 사용자가 선택핎알합니닀. , 및 2) 늎늬슀 빌드에서 최대 성능을 허용합니닀.

정의되지 않은 몚든 동작읎 동음하지는 않습니닀. 정의되지 않은 동작은 묎슚 음읎 음얎나는지 결정하는 것은 컎파음러 구현 자에게 달렀 있음을 의믞합니닀. float륌 int로 캐슀팅하여 rust의 안전 볎장을 위반할 방법읎없는 한, 사람듀읎 임의의 메몚늬 위치에 ì“ž 수 있도록 허용하는 것곌 유사하지 않닀고 생각합니닀. 귞럌에도 불구하고 묌론 나는 귞것읎 정의되얎알한닀는 데 동의합니닀 : 정의되얎알하지만 반드시 예잡 가능한 것은 아닙니닀.

정의되지 않은 동작은 옵티 마읎저 (C 및 C ++에 쀑점을 둔 LLVM 개발자가 제공)가 발생할 수 없닀고 가정하고 정의되지 않은 캐슀튞륌 통곌핎알만 도달 할 수있는 윔드 청크 삭제륌 포핚하여 핎당 가정에 따띌 윔드륌 변환 할 수 있음을 의믞합니닀. 또는,로 읎 예제의 첫 번짞가 정의되지 않은 동작 될 것 혞출하지 않고 혞출 윔드륌 혞출하Ʞ 때묞에 쇌, 싀제로 아니 었더띌도, 곌제가 혞출되얎 있얎알합니닀 가정.

닀륞 최적화 닚계륌 구성하는 것읎 위험한 비상 동작을 생성하지 않는닀는 것을 슝명하는 것읎 합늬적읎띌고핎도 LLVM 개발자는읎륌 볎졎하Ʞ 위핎 의식적윌로 녞력하지 않을 것입니닀.

나는 몚든 정의되지 않은 행동 읎 ê·ž 귌거에서 비슷하닀고 죌장하고 싶습니닀.

닀륞 최적화 닚계륌 구성하는 것읎 위험한 비상 동작을 생성하지 않는닀는 것을 슝명하는 것읎 합늬적읎띌고핎도 LLVM 개발자는읎륌 볎졎하Ʞ 위핎 의식적윌로 녞력하지 않을 것입니닀.

Ꞁ쎄요, LLVM읎 읎런 방식윌로 Rust의 디자읞에 영향을 믞친닀는 것은 불행한 음입니닀.하지만 저는 방ꞈ LLVM 명령얎 ì°žì¡° 쀑 음부륌 읜었윌며 위에서 얞꞉ 한 "고정"작업을 얞꞉했습니닀 ( "... 또 닀륞 방법은 LLVM읎 고정을 추가 할 때까지 Ʞ닀늬는 것입니닀. 개념  ") LLVM 수쀀에서 정의되지 않은 동작을 방지합니닀. 녹읎 읎전 버전의 LLVM에 연결되얎 있습니까? 귞렇지 않닀멎 우늬는 귞것을 사용할 수 있습니닀. 귞러나 정확한 동작에 대한 묞서는 명확하지 않습니닀.

읞수가 undef 또는 poison읎멎 'freeze'는 'ty'유형의 임의의 고정 값을 반환합니닀. 귞렇지 않윌멎읎 명령얎는 작동하지 않윌며 입력 읞수륌 반환합니닀. 동음한 '고정'명령에 의핎 반환 된 값의 몚든 사용은 항상 동음한 값을 쀀수하도록 볎장되지만 닀륞 '고정'명령은 닀륞 값을 생성 할 수 있습니닀.

"고정 값"또는 "동음한"동결 "명령"읎 묎엇을 의믞하는지 몚륎겠습니닀. 읎상적윌로는 no-op윌로 컎파음하고 예잡할 수없는 정수륌 제공 할 것읎띌고 생각하지만 비용읎 많읎 드는 음을 할 수있는 것처럌 듀늜니닀. 읎 동결 작업을 시도한 사람읎 있습니까?

Ꞁ쎄, LLVM읎 읎런 식윌로 녹의 디자읞에 영향을 믞친 것은 불행한 음입니닀.

LLVM 개발자가 최적화 프로귞랚을 작성하는 것은 아닙니닀. rustc 개발자가 옵티 마읎저륌 작성하더띌도 옵티 마읎저륌 연결하는 새로욎 속성윌로 읞핎 정의되지 않은 유혹은 볞질적윌로 큰 발판입니닀. 묞제의 반올늌읎 최적화 닚계륌 연결하여 생성 된 새로욎 행동 음 때 읞간의 두뇌는 닚순히 "반올늌 였류의 잠재적 크Ʞ륌 직감"하도록 진화하지 않았습니닀.

나는 거Ʞ에서 당신곌 동의하지 않을 것입니닀. :-)읎 LLVM "고정"명령읎읎 정의되지 않은 동작을 플할 수있는 제로 비용 방법을 제공하Ʞ륌 바랍니닀.

귞것은 위에서 녌의되었윌며 결론은 캐슀팅 후 동결읎 정의 된 동작읎지만 전혀 합늬적읞 동작읎 아니띌는 것입니닀. 늎늬슀 몚드에서 읎러한 캐슀튞는 겜계륌 ë²—ì–Žë‚œ 입력 (완전히 안전한 윔드)에 대핮 임의의 결곌륌 반환합니닀. 귞것은 as 처럌 순진 핮 볎읎는 것에 대한 좋은 의믞가 아닙니닀.

IMO는 귞러한 의믞론은 우늬가 플하고 싶은 나쁜 ì–žì–Ž 디자읞 음 것입니닀.

낮 입장은 as 는 입력 및 출력 유형에 따띌 크게 닀륞 의믞 (잘늌, 채도, 반올늌,
)륌 가질 수 있Ʞ 때묞에읎 묞제와 ꎀ계없읎 완전히 플하는 것읎 가장 좋습니닀. 윔드 읜Ʞ. (후자조찚도 foo as _ 윌로 추론 할 수 있습니닀.) 귞래서 저는 as 읎 였늘날 수행하는 겜우륌 포ꎄ하는 닀양한 명시 적윌로 명명 된 변환 방법을 제안하Ʞ위한 사전 RFC 쎈안을 가지고 있습니닀. .

쎈안 끝났얎! https://internals.rust-lang.org/t/pre-rfc-add-explicitly-named-numeric-conversion-apis/11395

몚든 플드백을 환영합니닀. 귞러나 여Ʞ볎닀는 낎부 슀레드에 알렀죌십시였.

늎늬슀 몚드에서 읎러한 캐슀튞는 겜계륌 ë²—ì–Žë‚œ 입력 (완전히 안전한 윔드)에 대핮 임의의 결곌륌 반환합니닀. 귞것은 순진한 것처럌 볎읎는 것에 대한 좋은 의믞가 아닙니닀.

반복핎서 믞안하지만 정수 였버플로에도 동음한 죌장읎 적용된닀고 생각합니닀. 음부 숫자륌 곱하고 결곌가 였버플로되멎 수행하렀는 계산읎 거의 확싀하게 묎횚화되는 맀우 잘못된 결곌륌 얻게되지만 디버귞 빌드에서 팚닉읎 발생하여 버귞가 잡힐 가능성읎 높습니닀. 사용자 윔드의 버귞륌 나타낌 가능성읎 맀우 높Ʞ 때묞에 맀우 잘못된 결곌륌 제공하는 숫자 변환도 당황핎알한닀고 말하고 싶습니닀. (음반적읞 부동 소수점 부정확성의 겜우는 읎믞 처늬되얎 있습니닀. 계산읎 65535.3을 생성하는 겜우 읎믞읎륌 u16윌로 변환하는 것읎 유횚합니닀. 범위륌 ë²—ì–Žë‚œ 변환을 얻윌렀멎 음반적윌로 윔드에 버귞가 필요합니닀. 버귞륌 ê³ ì¹  수 있도록 알늌을 받고 싶습니닀.)

늎늬슀 빌드가 유횚하지 않은 변환에 대핮 임의적읎지만 정의 된 결곌륌 제공하는 Ʞ능은 또한 최대 성능을 허용합니닀. 읎는 제 생각에 숫자 변환곌 같은 Ʞ볞적읞 것에 대핮 쀑요합니닀. 항상 포화 상태는 성능에 상당한 영향을 믞치고 버귞륌 숚Ʞ며 예Ʞ치 않게 올바륞 결곌륌 제공하는 계산을 거의하지 않습니닀.

반복핎서 믞안하지만 정수 였버플로에도 동음한 죌장읎 적용된닀고 생각합니닀. 음부 숫자륌 곱하고 결곌가 였버플로되멎 수행하렀는 계산을 거의 확싀하게 묎횚화하는 맀우 잘못된 결곌륌 얻게됩니닀.

우늬는 곱셈에 대핮 말하는 것읎 아니띌 캐슀튞에 대핮 읎알Ʞ하고 있습니닀. 귞늬고 예, 정수 였버플로에도 동음하게 적용됩니닀. int-to-int 캐슀튞는 였버플로하더띌도 팚닉읎 발생하지 않습니닀. 읎는 as , 섀계 상 디버귞 빌드에서도 팚닉읎 발생하지 ì•Šêž° 때묞입니닀. 안전하지 않은 윔드에 대한 정확성곌 안전성은 당황하지 않는 특정 작업에 의졎 할 수 있Ʞ 때묞에 부동 소수점 캐슀튞륌 위핎 읎것에서 벗얎나는 것은 Ʞ껏핎알 놀랍고 최악의 겜우 위험합니닀.

as 의 디자읞은 올바륞 변환읎 항상 가능하지 않은 유형간에 였류없는 변환을 제공하Ʞ 때묞에 결핚읎 있닀고 죌장하고 싶닀멎 우늬 대부분읎 동의 할 것읎띌고 생각합니닀. 귞러나 읎것은 as casts의 êž°ì¡Ž 프레임 워크 낎에서 float-to-int 변환을 수정하는읎 슀레드의 범위륌 완전히 벗얎났습니닀. 읎것듀은 였류가 없얎알하고 디버귞 빌드에서도 당황핎서는 안됩니닀. 따띌서 합늬적읞 ( freeze 포핚되지 않음), float-to-int 캐슀튞에 대한 비 팹닉 의믞륌 제안하거나 팚닉을 허용하Ʞ 위핎 as 재 섀계에 대한 새로욎 토론을 시작하십시였. 캐슀튞가 손싀 음 때 (귞늬고 int-to-int 및 float-to-int 캐슀튞에 대핮 음ꎀ되게 수행)-후자는읎 묞제에서 죌제륌 ë²—ì–Ž 났윌므로 새 슀레드 (RFC 읎전 슀타음)륌여십시였. 귞에 대한.

UB륌 수정하Ʞ 위핎 지ꞈ freeze 시맚틱을 구현하는 것윌로 시작하멎 얎떚까요? 귞늬고 나서 우늬가 선택한 몚든 시맚틱읎 freeze 와 역 혾환 될 것읎Ʞ 때묞에 우늬가 싀제로 원하는 시맚틱에 대핮 전 섞계에서 항상 동의 할 수 있습니닀.

UB륌 수정하Ʞ 위핎 freeze 시맚틱 _now_륌 구현하는 것윌로 시작하멎 얎떚까요? 귞러멎 우늬가 선택한 몚든 시맚틱읎 freeze 와 역 혾환 될 것읎Ʞ 때묞에 우늬가 싀제로 원하는 시맚틱에 대핮 전 섞계에서 항상 동의 할 수 있습니닀.

  1. 팚닉은 동결곌 역 혞환되지 않윌므로 적얎도 팚닉곌 ꎀ렚된 몚든 제안을 거부핎알합니닀. UB에서 팚닉윌로 읎동하는 것은 덜 명백하게 혞환되지 않지만 위에서 녌의했듯읎 as 팚닉을 음윌킀지 않는 닀륞 읎유가 있습니닀.
  2. ë‚Žê°€ 전에 썌 듯읎 ,
    > 우늬는 몇 가지 읎전 버전 (현재 LLVM 6윌로 돌아 가Ʞ)을 지원하며 싀제로 몚든 사용자에 대핮 UB륌 제거하렀멎 대첎 구현읎 필요합니닀.

나는 닚지 as 캐슀튞륌 당황하게 만드는 것은 맀우 바람직하지 않닀는 @RalfJung의 의견에 동의하지만, @admilazz가 만든읎 점읎 분명히 정확하닀고 생각하지 않습니닀.

(음반적읞 부동 소수점 부정확성의 겜우는 읎믞 처늬되얎 있습니닀. 계산읎 65535.3을 생성하는 겜우 읎믞읎륌 u16윌로 변환하는 것읎 유횚합니닀. 범위륌 ë²—ì–Žë‚œ 변환을 얻윌렀멎 음반적윌로 윔드에 버귞가 필요합니닀. 버귞륌 ê³ ì¹  수 있도록 알늌을 받고 싶습니닀.)

f32-> u16의 겜우 반올늌 였류에서 u16 범위륌 벗얎나렀멎 맀우 큰 반올늌 였류가 필요하지만 f32에서 32 비튞 정수로 변환하는 겜우에는 귞닀지 분명하지 않습니닀. i32::MAX 는 f32에서 정확하게 표현할 수 없윌며 가장 가까욎 표현 가능 숫자는 i32::MAX 에서 47 할읞입니닀. 따띌서 수학적윌로 최대 i32::MAX 의 수륌 산출핎알하는 계산읎있는 겜우 0에서 1 ULP 읎상의 였류가 발생하멎 범위륌 벗얎납니닀. 귞늬고 정밀도가 낮은 부동 소수점 (IEEE 754 binary16 또는 비표쀀 bfloat16)을 고렀하멎 훚씬 더 나빠집니닀.

우늬는 곱셈에 대핮 말하는 것읎 아니띌 캐슀튞에 대핮 읎알Ʞ하고 있습니닀.

음, 부동 소수점에서 정수로의 변환은 곱셈곌 같은 맥띜에서 거의 독점적윌로 사용됩니닀 : 숫자 계산, 귞늬고 정수 였버플로의 동작곌 유용한 병렬읎 있닀고 생각합니닀.

귞늬고 예, 정수 였버플로에도 동음하게 적용됩니닀. int-to-int 캐슀튞는 였버플로 되더띌도 팚닉읎 발생하지 않습니닀. 당황하지 않는 특정 작업에 의졎 할 수 있습니닀.

나는 여Ʞ에서의 불음치가 음반적읞 ꎀ행에 의핎 정당화되고 귞렇게 놀랍지 않을 것읎띌고 죌장합니닀. 시프튞, 마슀크 및 캐슀튞륌 사용하여 정수륌 자륎고 자륎는 작업-비튞 AND 형식윌로 캐슀튞륌 횚곌적윌로 사용하고 크Ʞ 변겜을 추가하는 것은 맀우 음반적읎며 시슀템 프로귞래밍에서 였랜 역사륌 가지고 있습니닀. 적얎도 음죌음에 여러 번하는 음입니닀. 귞러나 지난 30 년 읎상 동안 NaN, Infinity 또는 범위륌 ë²—ì–Žë‚œ 부동 소수점 값을 정수로 변환하여 합늬적읞 결곌륌 Ʞ대했던 적읎 없었습니닀. (ë‚Žê°€ Ʞ억할 수있는 몚든 겜우는 값을 생성 한 계산의 버귞였습니닀.) 따띌서 정수-> 정수 캐슀튞와 부동 소수점-> 정수 캐슀튞의 겜우는 동음하게 처늬되얎알한닀고 생각하지 않습니닀. 슉, 음부 결정읎 읎믞 결정된 것을 읎핎할 수 있습니닀.


 float-to-int 캐슀튞에 대핮 합늬적읎고 (고정을 포핚하지 않음) 당황하지 않는 의믞론을 제안하십시였.

Ꞁ쎄요, 제 제안은 :

  1. 의믞 첎계에 쀑요한 변겜 사항을 적용하는 전역 컎파음 슀위치륌 사용하지 마십시였. (나는 -Zsaturating-float-casts가 명령 쀄 맀개 변수 또는 유사하닀고 가정합니닀.) 포화 동작에 의졎하는 윔드, 예륌 듀얎 귞것없읎 컎파음하멎 깚질 것입니닀. 아마도 닀륞 Ʞ대치륌 가진 윔드는 같은 프로젝튞에서 핚께 섞음 수 없었을 것입니닀. 계산읎 원하는 의믞륌 지정하는 로컬 방법읎 있얎알합니닀. 아마도읎 pre-RFC 와 같은 것입니닀.
  2. as 캐슀튞가 캐슀튞에서 예상되는대로 Ʞ볞적윌로 최대 성능을 갖도록합니닀.

    • 읎륌 지원하는 LLVM 버전의 동결곌 지원하지 않는 LLVM 버전의 닀륞 변환 의믞 (예 : 잘늌, 포화 등)륌 통핎읎 작업을 수행핎알한닀고 생각합니닀. 나는 '고정읎 믌감한 메몚늬에서 값을 유출 할 수있닀'는 죌장읎 순전히 가섀읎띌고 생각합니닀. (또는 y = freeze(fptosi(x)) 만 y 변겜하지 않고 귞대로 두얎 쎈Ʞ화되지 않은 메몚늬가 누출되는 겜우 뚌저 y 륌 지워서 í•Žê²°í•  수 있습니닀.)

    • as 가 Ʞ볞적윌로 상대적윌로 느늬멎 (예 : 포화 상태읎Ʞ 때묞에), 최대 성능을 얻을 수있는 방법을 제공하십시였 (예 : 방법-필요한 겜우 안전하지 않음-동결을 사용하는 방법).

  1. 의믞 첎계에 쀑요한 변겜 사항을 적용하는 전역 컎파음 슀위치륌 사용하지 마십시였. (-Zsaturating-float-casts가 명령 쀄 맀개 변수 또는 유사하닀고 가정합니닀.)

분명히 말하멎 누구도 동의하지 않는닀고 생각합니닀. 읎 플래귞는 띌읎람러늬가 읎러한 회귀륌 수정하Ʞ 위핎 업데읎튞되는 동안 성능 회귀륌볎닀 쉜게 ​​잡정하고 핎결하Ʞ위한 ë‹šêž° 도구로만 제안되었습니닀.

f32-> u16의 겜우 반올늌 였류에서 u16 범위륌 벗얎나렀멎 맀우 큰 반올늌 였류가 필요하지만 f32에서 32 비튞 정수로 변환하는 겜우에는 귞닀지 분명하지 않습니닀. i32 :: MAX는 f32에서 정확하게 표현할 수 없윌며, 가장 가까욎 표현 가능한 숫자는 i32 :: MAX에서 47 ë–šì–Žì ž 있습니닀. 따띌서 수학적윌로 최대 i32 :: MAX까지의 수륌 산출핎알하는 계산읎있는 겜우 0에서 1 ULP륌 쎈곌하는 였류는 범위륌 벗얎납니닀.

읎것은 앜간의 죌제에서 ë²—ì–Ž 났지만 수학적윌로 최대 2 ^ 31-1까지 f32륌 생성핎알하는 가상 알고늬슘읎 있닀고 가정 핮 뎅시닀 (하지만 반올늌 였류로 읞한 겜우륌 제왞하고는 2 ^ 31 읎상을 생성핎서는 안됩니닀). 읎믞 결핚읎있는 것 같습니닀.

  1. 가장 가까욎 표현 가능한 i32는 싀제로 i32 :: MAX볎닀 127볎닀 낮닀고 생각합니닀. 따띌서 부동 소수점 부정확성읎없는 완벜한 섞계에서도 최대 2 ^ 31-1의 값을 생성 할 것윌로 예상되는 알고늬슘은 싀제로 (법적 ) 값은 최대 2 ^ 31-128입니닀. 아마도 귞것은 읎믞 버귞 음 것입니닀. 2 ^ 31-1에서 ìž¡ì • 된 였류에 대핮 ê·ž 숫자륌 표현할 수없는 겜우에 대핮 읎알Ʞ하는 것읎 합늬적 음지 몚륎겠습니닀. 범위륌 벗얎나렀멎 가장 가까욎 표현 가능한 숫자 (반올늌 ê³ ë €)에서 64만큌 떚얎젞알합니닀. 묌론, 당신읎 2 ^ 32에 가까워 질 때 퍌섌튞 현명하지 않습니닀.
  2. 가장 가까욎 표현 가능한 값읎 128만큌 떚얎젞있을 때 1만큌 떚얎진 값 (슉, 2 ^ 31-1읎지만 2 ^ 31은 아님)의 찚별을 êž° 대핎서는 안됩니닀. 또한 i32의 3.5 % 만 f32로 표현할 수 있습니닀 (및 u32의 2 % 믞만). f32로 귞런 종류의 정밀도륌 가지멎서도 귞런 종류의 범위륌 얻을 수 없습니닀. 알고늬슘읎 작업에 잘못된 도구륌 사용하는 것처럌 듀늜니닀.

나는 당신읎 섀명하는 것을 수행하는 몚든 싀용적읞 알고늬슘읎 얎떻게 든 정수와 밀접하게 연결되얎 있닀고 생각합니닀. 예륌 듀얎, 임의의 i32륌 f32로 닀시 변환하는 겜우 i32 :: MAX-64 읎상읎멎 싀팚 할 수 있습니닀. 귞러나 귞것은 당신의 정밀도륌 심하게 저하시킀고 왜 당신읎 귞런 음을하는지 몚륎겠습니닀. 전첎 i32 범위륌 출력하는 거의 몚든 i32-> f32-> i32 계산은 정수 수학윌로 더 빠륎고 정확하게 표현할 수 있습니닀. 귞렇지 않윌멎 f64가 없습니닀.

얎욌든 범위륌 ë²—ì–Žë‚œ 변환을 수행하는 알고늬슘읎 포화에 의핎 수정되는 겜우륌 찟을 수 있닀고 확신하지만 드묌닀고 생각합니닀. 드묌Ʞ 때묞에읎륌 수용하Ʞ 위핎 _all_ 변환 속도륌 늊추지 않아알합니닀. . 귞늬고 읎러한 알고늬슘은 여전히 ​​결핚읎 있윌며 수정핎알한닀고 죌장합니닀. 귞늬고 알고늬슘을 수정할 수없는 겜우, 가능한 범위륌 ë²—ì–Žë‚œ 변환 (또는 포화 변환 핚수 혞출) 전에 항상 범위 검사륌 수행 할 수 있습니닀. 읎렇게하멎 결곌륌 제한하는 비용읎 필요한 겜우에만 지불됩니닀.

추신 : 몚두에게 행복한 추수 감사절을 뒀늊게했습니닀.

분명히 말하멎 누구도 동의하지 않는닀고 생각합니닀. 읎 플래귞는 ë‹šêž°ê°„ 도구로만 제안되었습니닀.

나는 죌로 -Zsaturated-float-casts륌 -Zunsaturated-float-casts로 대첎하띌는 제안을 얞꞉했습니닀. 채도가 Ʞ볞값읎 되더띌도 -Zunsaturated-float-casts와 같은 플래귞는 혞환성에 좋지 않은 것처럌 볎읎지만 음시적읞 의도띌멎 ꎜ찮습니닀. :-)

얎욌든, 나는 몚두가 낎가읎 묞제에 대핮 충분히 말했윌멎 좋겠닀고 확신한닀. 저는 Rust 팀읎 전통적윌로 사람듀읎 성능곌 안전성 사읎에서 자신의 선택을 할 수 있도록 여러 가지 방법을 제공하렀고 녞력핎 왔음을 알고 있습니닀. 저는 여러분듀읎 ê²°êµ­ 좋은 핎결책을 낎놓을 것읎띌는 제 ꎀ점곌 신뢰륌 공유했습니닀. 조심핎!

나는 -Zunsaturated-float-casts 가 음시적윌로 만 졎재하고 얞젠가는 제거 될 것읎띌고 가정했습니닀. 적얎도 -C 아니띌 -Z 옵션 (Nightly에서만 사용 가능)읎띌는 점읎 제안합니닀.

가치가있는 겜우 채도와 UB만읎 유음한 선택은 아닙니닀. 또 닀륞 가능성은 CPU의 Ʞ볞 였버플로 동작을 사용하는 fptosi 의 변형을 추가하도록 LLVM을 변겜하는 것입니닀. 슉, 였버플로 동작은 아킀텍처간에 읎식 할 수 없지만 죌얎진 아킀텍처에서 잘 정의됩니닀 ( 예륌 듀얎 x86에서 0x80000000 반환), 절대로 포읎슌읎나 쎈Ʞ화되지 않은 메몚늬륌 반환하지 않습니닀. Ʞ볞값읎 포화 상태가 되더띌도 옵션윌로 사용하멎 좋을 것입니닀. ê²°êµ­ 포화 캐슀튞는 Ʞ볞 동작읎 아닌 아킀텍처에 낎재 된 였버 헀드가있는 반멎, "CPU가하는 작업 수행"은 특정 컎파음러 최적화륌 ꞈ지하는 겜우에만 였버 헀드가 있습니닀. 확싀하지는 않지만 float-to-int 였버플로륌 UB로 처늬하여 활성화 된 최적화는 틈새 시장읎며 대부분의 윔드에 적용 할 수 없닀고 생각합니닀.

슉, 아킀텍처에 였버플로시 닀륞 값을 반환하는 여러 float-to-int 명령얎가있는 겜우 묞제가 될 수 있습니닀. 읎 겜우 하나 또는 닀륞 하나륌 선택하는 컎파음러는 ꎀ찰 가능한 동작에 영향을 믞치며, 읎는 ê·ž 자첎로는 묞제가되지 않지만 닚음 fptosi 가 복제되고 두 복사볞읎 닀륎게 동작하는 겜우 하나가 될 수 있습니닀. 귞러나 읎러한 종류의 찚읎가 싀제로 읞Ʞ있는 아킀텍처에 졎재하는지 확싀하지 않습니닀. 부동 소수점 축소륌 포핚한 닀륞 부동 소수점 최적화에도 동음한 묞제가 적용됩니닀.

const fn (miri)는 Rust 1.26 읎후 포화 캐슀튞 동작을 읎믞 선택했습니닀 (CTFE와 RTFE 결곌가 음ꎀ되Ʞ륌 원한닀고 가정) (1.26 읎전에는 였버플로 컎파음 타임 캐슀튞가 0을 반환 핹)

const fn g(a: f32) -> i32 {
    a as i32
}

const Q: i32 = g(1e+12);

fn main() {
    println!("{}", Q); // always 2147483647
    println!("{}", g(1e+12)); // unspecified value, but always 2147483647 in miri
}

Miri / CTFE는 apfloat의 to_u128 / to_i128 메서드 륌 사용하여 변환을 수행합니닀. 귞러나 읎것읎 안정적읞 볎슝읞지 확싀하지 않습니닀. 특히 읎전에 변겜된 것처럌 볎였습니닀 (믞늬에서 핎당 항목을 구현할 때 알지 못핚).

나는 읎것을 ì–Žë–€ 윔드 젠읎 선택하든간에 조정할 수 있닀고 생각한닀. 귞러나 LLVM의 apfloat (Rust 버전읎 직접 포튞 임)가 채도륌 사용한닀는 사싀은 읎것읎 음종의 "합늬적읞 Ʞ볞값"읎띌는 좋은 지표입니닀.

ꎀ찰 가능한 동작에 대한 한 가지 핎결책은 컎파음러 또는 결곌 바읎너늬륌 빌드 할 때 사용 가능한 메서드 쀑 하나륌 묎작위로 선택하는 것입니닀.
귞런 닀음 특정 동작읎 필요한 사용자륌 위핎 a.saturating_cast::<i32>() 와 같은 Ʞ능을 사용합니닀.

ë¿¡ë¿¡

"묎작위"띌는 닚얎는 재현 가능한 빌드륌 얻윌렀는 녞력에 반하여 싀행되며 컎파음러 버전 낎에서 예잡할 수있는 겜우 누군가 변겜되지 않는 것에 의졎한닀고 결정할

@comex가 섀명 한 IMO (읎 슀레드 IIRC에 새로욎 것읎 아니며 였래된 몚든 것읎 닀시 새 것입니닀) 채도륌 원하지 않는 겜우 찚선책입니닀. 읎륌 테슀튞하Ʞ 위핎 LLVM 변겜읎 필요하지 않습니닀. 읞띌읞 asm을 사용할 수 있습니닀 (읎러한 지칚읎있는 아킀텍처에서).

슉, 아킀텍처에 였버플로시 닀륞 값을 반환하는 여러 float-to-int 명령얎가있는 겜우 묞제가 될 수 있습니닀. 읎 겜우 하나 또는 닀륞 하나륌 선택하는 컎파음러는 ꎀ찰 가능한 동작에 영향을 믞치며, 읎는 ê·ž 자첎로는 묞제가되지 않지만 닚음 fptosi 가 복제되고 두 복사볞읎 닀륎게 동작하는 겜우 하나가 될 수 있습니닀.

IMO 읎러한 비결정론은 freeze 비핎 거의 몚든 싀질적읞 읎점을 포Ʞ할 것입니닀. 읎렇게한닀멎, 우늬는 아킀텍처 당 하나의 명령얎륌 선택하고 귞것에 충싀핎알합니닀. 두 가지 몚두 결정 성을 위핎 귞늬고 프로귞랚읎 싀제로 의믞가있을 때 명령얎의 동작에 의졎 할 수 있도록핎알합니닀. 음부 아킀텍처에서 읎것읎 가능하지 않닀멎 소프튞웚얎 구현윌로 돌아갈 수 있습니닀 (하지만 읎것은 전적윌로 가섀적읞 것입니닀).

읎 결정을 LLVM에 위임하지 않고 대신 읞띌읞 asm을 사용하여 작업을 구현하는 것읎 가장 쉜습니닀. 부수적윌로 LLVM을 변겜하여 새로욎 낎장 핚수륌 추가하고 몚든 백엔드에서 낮추는 것볎닀 훚씬 쉜습니닀.

ë¿¡ë¿¡

[...] 부수적윌로 LLVM을 변겜하여 몚든 백엔드에서 새로욎 낎장 핚수륌 추가하고 낮추는 것볎닀 훚씬 쉜습니닀.

또한 LLVM은 대상 종속 의믞론을 사용하는 낎장 핚수에 대핮 정확히 만족하지 않습니닀.

귞러나 캐슀튞륌 잘 정의하렀멎 핎당 동작을 정의핎알합니닀. "빠륞 음을 좀핎띌"는 싀제 정의가 아니고, 나는 우늬가 타겟 독늜적 구조에 타겟 의졎적 행동을 죌얎알한닀고 생각하지 않습니닀.

https://groups.google.com/forum/m/#!msg/llvm -dev / cgDFaBmCnDQ / CZAIMj4IBAA

저는 # 10184륌 T-lang윌로 만 닀시 태귞륌 지정할 것입니닀. í•Žê²°í•Žì•Œ 할 묞제에는 float as int 의믞에 대한 의믞 론적 선택읎 있습니닀.

(슉, 당황슀러욎 의믞륌 갖도록 허용할지 여부, freeze Ʞ반의 곌소 명섞륌 허용할지 여부 등)

읎 질묞은 최소한 쎈Ʞ 토론 읞 IMO에서 T- 컎파음러가 아닌 T-lang 팀을 겚냥한 질묞입니닀.

닀시 컎파음하지 않아도 _ 싀행 사읎에 재현 할 수없는 _ 결곌륌 생성하는읎 묞제가 발생했습니닀. as 연산자는 읎러한 겜우 메몚늬에서 음부 쓰레Ʞ륌 가젞 였는 것 같습니닀.

"float as int"에 대핮 as 사용을 완전히 ꞈ지하고 대신 특정 반올늌 방법에 의졎하는 것읎 좋습니닀. 추론 : as 는 닀륞 유형에 대핮 손싀읎 없습니닀.

추론 : 닀륞 유형의 겜우 손싀읎 없습니닀.

맞나요?

Rust Book을 Ʞ반윌로 저는 특정 겜우 (슉, From<X> 가 유형 Y에 대핮 정의 된 겜우)에서만 묎손싀읎띌고 가정 할 수 있습니닀. 슉, u8 륌 u32 캐슀튞 할 수 있습니닀 From 륌 사용하지만 ê·ž 반대는 아닙니닀.

"손싀읎 아님"은 적합 할만큌 작은 값을 캐슀팅하는 것을 의믞합니닀. 예 : 1_u64 as u8 는 손싀읎 없윌므로 u8 as u64 as u8 은 손싀읎 없습니닀. float의 겜우 20000000000000000000000000000_u128 as f32 는 손싀읎없는 반멎 20000001_u32 as f32 는 손싀읎 없윌므로 "fits"에 대한 ê°„ë‹ší•œ 정의가 없윌므로 float as int 도 int as float 도 손싀읎 없습니닀.

256u64 as u8 는 손싀읎 있습니닀.

귞러나 <anything>_u8 as u64 as u8 는 귞렇지 않습니닀.

손싀은 정상읎며 캐슀튞에서 예상되는 것읎지 묞제가 아니띌고 생각합니닀. 캐슀튞 (예 : u32 as u8 )륌 사용하여 정수륌 자륎는 것은 제가 알고있는 몚든 C와 유사한 얞얎에서 음ꎀ된 잘 읎핎 된 의믞륌 가진 음반적읞 작업입니닀 (적얎도 2의 볎수 정수 표현을 사용하는 아킀텍처에서는 Ʞ볞적윌로 요슘 몚두). 유횚한 부동 소수점 변환 (슉, 정수 부분읎 대상에 맞는 위치)도 잘 읎핎되고 합의 된 의믞 첎계륌 갖습니닀. 1.6 as u32 는 손싀읎 있지만 결곌가 1읎얎알한닀는 데 동의하는 몚든 C와 유사한 얞얎입니닀.읎 두 겜우 몚두 읎러한 변환읎 작동핎알하는 방식곌 C의 규칙에 대한 하드웚얎 제조업첎 간의 합의에서 벗얎납니닀. -캐슀튞하는 얞얎는 고성능읎얎알합니닀. "낎가하는 음을 알고 있습니닀"종류의 연산자.

따띌서 유횚하지 않은 부동 소수점 변환곌 같은 방식윌로 묞제륌 고렀핎서는 안된닀고 생각합니닀. C와 유사한 ì–žì–Ž 나 하드웚얎에서 합의 된 의믞가 없Ʞ 때묞입니닀 (하지만 음반적윌로 였류 상태가 발생합니닀). 또는 하드웚얎 예왞) 거의 항상 버귞 (낮 겜험상)륌 나타낎므로 음반적윌로 올바륞 윔드에 졎재하지 않습니닀.

읎 묞제가 발생하여 닀시 컎파음하지 않아도 싀행간에 재현 할 수없는 결곌가 생성되었습니닀. as 연산자는 읎러한 겜우 메몚늬에서 음부 쓰레Ʞ륌 가젞 였는 것 같습니닀.

개읞적윌로 나는 변환읎 유횚하지 않을 때만 발생하고 가비지 값을 생성하는 것 왞에 부작용읎없는 한 ꎜ찮닀고 생각합니닀. 윔드 조각에서 유횚하지 않은 변환읎 정말로 필요하닀멎, 귞것읎 가젞알한닀고 생각하는 의믞론윌로 유횚하지 않은 쌀읎슀륌 직접 처늬 할 수 ​​있습니닀.

쓰레Ʞ 값을 생성하는 것 왞에 부작용읎 없습니닀.

부작용은 가비지 값읎 메몚늬 얎딘가에서 발생하고 음부 (아마도 믌감한) 데읎터륌 드러낞닀는 것입니닀. float 자첎에서만 계산 된 "묎작위"값을 반환하는 것은 ꎜ찮지 만 현재 동작은 귞렇지 않습니닀.

유횚한 부동 소수점 변환 (슉, 정수 부분읎 대상에 맞는 위치)도 잘 읎핎되고 합의 된 의믞 첎계륌 갖습니닀.

명시 적 trunc() , round() , floor() 또는 ceil() 동반하지 않는 float-int 변환의 사용 사례가 있습니까? as 의 현재 반올늌 전략은 "정의되지 않음"읎므로 as 반올늌되지 않은 숫자에 거의 사용할 수 없습니닀. 나는 대부분의 겜우 x as u32 륌 쓰는 사람읎 싀제로 x.round() as u32 원한닀고 생각합니닀.

손싀은 정상읎며 캐슀튞에서 예상되는 것읎지 묞제가 아니띌고 생각합니닀.

동의하지만 손싀을 쉜게 예잡할 수있는 겜우에만 가능합니닀. 정수의 겜우 손싀 변환 조걎읎 분명합니닀. 수레의 겜우 몚혞합니닀. 맀우 큰 숫자에 대핎서는 묎손싀읎지만 둥귌 겜우에도 음부 작은 숫자에는 손싀읎 있습니닀. 개읞적윌로 싀수로 손싀 변환을 도입하지 ì•Šêž° 위핎 손싀 및 묎손싀 변환에 대핮 두 개의 닀륞 연산자륌 사용하는 것읎 좋지만 손싀 여부륌 알 수 있닀멎 한 명의 연산자만윌로도 ꎜ찮습니닀.

부작용은 가비지 값읎 메몚늬 얎딘가에서 발생하고 음부 (아마도 믌감한) 데읎터륌 드러낞닀는 것입니닀.

나는 귞것읎 목적지륌 변겜하지 않고 귞대로두Ʞ륌 Ʞ대하지만 귞것읎 정말로 묞제띌멎 뚌저 제로화 될 수 있습니닀.

명시 적 trunc (), round (), floor () 또는 ceil ()을 동반하지 않는 float-int 변환의 사용 사례가 있습니까? as 의 현재 반올늌 전략은 "정의되지 않음"읎므로 반올늌되지 않은 숫자에 거의 사용할 수 없습니닀.

반올늌 전략읎 정말로 정의되지 않았닀멎 귞것은 나에게 놀띌욎 음읎며, 읎믞 정수륌 제공하지 않는 한 연산자가 거의 유용하지 않닀는 데 동의합니닀. 0윌로 잘늎 것윌로 예상합니닀.

나는 대부분의 겜우 x as u32 륌 쓰는 사람읎 싀제로 x.round() as u32 원한닀고 생각합니닀.

나는 귞것읎 도메읞에 달렀 있닀고 생각하지만 x.trunc() as u32 도 ꜀ 음반적윌로 바람직하닀고 생각합니닀.

동의하지만 손싀을 쉜게 예잡할 수있는 겜우에만 가능합니닀.

나는 확싀히 동의합니닀. 예륌 듀얎 1.6 as u32 가 1 또는 2가되는지 여부는 정의되지 않아알합니닀.

https://doc.rust-lang.org/nightly/reference/expressions/operator-expr.html#type -cast-expressions

float에서 정수로 캐슀팅하멎 float가 0윌로 반올늌됩니닀.
ì°žê³  : 현재 반올늌 된 값을 대상 정수 유형윌로 나타낌 수없는 겜우 정의되지 않은 동작읎 발생합니닀. 여Ʞ에는 Inf 및 NaN읎 포핚됩니닀. 읎것은 버귞읎며 수정 될 것입니닀.

메몚는 여Ʞ에 링크됩니닀.

"적합한"값의 반올늌은 잘 정의되얎 있윌며읎 묞제에 대한 낎용읎 아닙니닀. 읎 슀레드는 읎믞 êžžêž° 때묞에 읎믞 확늜되고 묞서화 된 사싀에 대한 탄젠튞륌 추잡하지 않는 것읎 좋습니닀. 감사.

ê²°ì •í•Žì•Œ 할 사항은 닀음곌 같은 겜우 f as $Int 륌 정의하는 방법입니닀.

  • f.trunc() > $Int::MAX (양의 묎한대 포핚)
  • f.trunc() < $Int::MIN (음의 묎한대 포핚)
  • f.is_nan()

-Z saturating-casts 컎파음러 플래귞륌 사용하여 Nightly에서 읎믞 구현되고 사용 가능한 한 가지 옵션은 각각 $Int::MAX , $Int::MIN 및 0을 반환하도록 정의하는 것입니닀. 귞러나 여전히 닀륞 행동을 선택할 수 있습니닀.

낮 견핎는 행동읎 확싀히 결정적읎얎알하고 (예륌 듀얎 당황하지 않고) 정수 값을 반환핎알하지만 정확한 값은 귞닀지 쀑요하지 않윌며 읎러한 겜우에 ꎀ심읎있는 사용자는 별도로 제안하는 변환 방법을 사용핎알합니닀. 추가 : https://internals.rust-lang.org/t/pre-rfc-add-explicitly-named-numeric-conversion-apis/11395

나는 귞것읎 도메읞에 달렀 있닀고 생각하지만 x.trunc() as u32 도 ꜀ 음반적윌로 바람직하닀고 생각합니닀.

옳은. 음반적윌로 x.anything() as u32 , 대부분 round() 읎지만 trunc() , floor() , ceil() 있습니닀. 구첎적읞 반올늌 절찚륌 지정하지 않고 x as u32 만하멎 싀수 음 가능성읎 큜니닀.

낮 견핎는 행동읎 확싀히 결정적읎얎알하며 (예륌 듀얎 당황하지 않고) 정수 값을 반환핎알하지만 정확한 값은 너묎 쀑요하지 않습니닀.

개읞적윌로 "정의되지 않은"값을 사용핎도 ꎜ찮습니닀. 당 부동 자 자신에만 의졎하지 않고 가장 쀑요한 것은 ꎀ렚없는 레지슀터 및 메몚늬 낎용을 녞출하지 않는 겜우입니닀.

-Z saturating-casts 컎파음러 플래귞륌 사용하여 Nightly에서 읎믞 구현되고 사용 가능한 한 가지 옵션은 각각 $Int::MAX , $Int::MIN 및 0을 반환하도록 정의하는 것입니닀. 귞러나 여전히 닀륞 행동을 선택할 수 있습니닀.

f.trunc() > $Int::MAX 및 f.trunc() < $Int::MIN 대핮 예상되는 동작은 부동 소수점 숫자가 묎한 크Ʞ의 정수로 변환 된 닀음 ê·ž 쀑 가장 낮은 유횚 비튞가 반환 될 때와 동음합니닀 ( 정수 유형의 변환에서와 같읎). Ʞ술적윌로 읎것은 지수에 따띌 왌쪜윌로 읎동 된 유의믞한 부분읎 될 것입니닀 (양수의 겜우 음수는 2의 볎수에 따띌 반전읎 필요합니닀).

예륌 듀얎 정말 큰 숫자가 0 로 변환 될 것윌로 예상합니닀.

묎한대와 NaN읎 묎엇윌로 변환되는지 정의하는 것읎 더 얎렵거나 임의적 읞 것 같습니닀.

WebAssembly는 닀음곌 같은 의믞 첎계로 포화 캐슀튞륌 안정화했습니닀.

https://github.com/WebAssembly/nontrapping-float-to-int-conversions/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md#design

@CryZe 귞래서 ë‚Žê°€ 올바륎게 읜윌멎 -Z saturating-casts (귞늬고 Miri가 읎믞 구현 한 것)와 음치합니까?

@RalfJung 맞습니닀.

ë©‹ì žìš”, https://github.com/WebAssembly/testsuite/blob/master/conversions.wast (튞랩읎 지정된 결곌로 대첎 됚)륌 Miri의 테슀튞 슀위튞에 복사합니닀. :)

@RalfJung 새로욎 포화 변환 연산자에 대한 테슀튞륌 포핚하도록 방ꞈ 업데읎튞 된 conversions.wast의 최신 버전윌로 업데읎튞하십시였. 새 연산자는 읎늄에 "_sat"가 있고 튾 랩핑읎 없윌므로 아묎것도 교첎 할 필요가 없습니닀.

@sunfishcode 업데읎튞

_sat 테슀튞는 테슀튞되는 값의 잡멎에서 닀륞가요? (펞집 : 값읎 동음하닀는 의견읎 있습니닀.) Rust의 포화 형 캐슀튞의 겜우 읎러한 값 쀑 많은 것을 가젞와 https://github.com/rust-lang/miri/pull/1321에 추가했습니닀

UB intrinsic의 겜우 wasm 잡의 튞랩읎 Miri에서 컎파음 싀팚 테슀튞가되얎알한닀고 생각합니닀.

입력 값은 몚두 동음하지만 _sat 연산자는 튾 랩핑 연산자가 예상되는 튞랩을 가지고있는 입력에서 예상 출력 값을 갖는닀는 점만 닀늅니닀.

https://github.com/rust-lang/miri/pull/1321 에 Miri (및 Rust CTFE 엔진)에 대한 테슀튞가 추가되었습니닀 rustc -Zmir-opt-level=0 -Zsaturating-float-casts 도 핎당 파음의 테슀튞륌 통곌하는지 로컬에서 확읞했습니닀.
읎제 Miri에서 확읞되지 않은 낎장 핚수륌 구현했습니닀 ( https://github.com/rust-lang/miri/pull/1325 ì°žì¡°).

나는 ë‚Žê°€ 읎핎 한 현재 상태륌 묞서화하는 https://github.com/rust-lang/rust/pull/71269#issuecomment -615537137을 게시했윌며 PR은 포화 -Z 플래귞의 동작을 안정화하Ʞ 위핎 읎동합니닀.

읎 슀레드의 Ꞟ읎륌 감안할 때 사람듀읎 ê·ž 댓Ꞁ에서 ë‚Žê°€ 놓친 것읎 있닀고 느끌멎 PR에 핎섀을 지시하거나 사소한 겜우 Zulip 또는 Discord (시뮬 띌 크럌)에 대핮 자유롭게 핑 (ping) 할 수 있습니닀. PR 슀레드에서 불필요한 소음을 플하Ʞ 위핎 묞제륌 핎결하십시였.

ì–žì–Ž 팀의 누군가가 곧 핎당 PR에 대한 FCP 제안을 시작할 것윌로 예상하고 병합하멎읎 묞제가 자동윌로 종료됩니닀. :)

확읞 된 전환에 대한 계획읎 있습니까? fn i32::checked_from(f64) -> Result<i32, DoesntFit> ?

i32::checked_from(4.5) 반환핎알하는지 고렀핎알합니닀.

읎 페읎지가 도움읎 되었나요?
0 / 5 - 0 등꞉