การเพิ่มประสิทธิภาพคอมไพเลอร์จะขจัดสตริงและอาร์เรย์ที่ซ้ำกัน

ภาพบุคคล2018facebook.jpg

เมื่อตั้งโปรแกรม การจัดเก็บข้อมูลคงที่แบบเดิมซ้ำแล้วซ้ำเล่าอาจเป็นเรื่องที่สิ้นเปลือง คุณใช้หน่วยความจำมากขึ้น คุณเข้าถึงข้อมูลได้มากขึ้น โชคดีที่คอมไพเลอร์เพิ่มประสิทธิภาพของคุณอาจช่วยได้

พิจารณารหัส C สองบรรทัดต่อไปนี้:

 printf ( " สวัสดีครับ ศาสตราจารย์โจนส์ " ) ;   
printf ( " อรุณสวัสดิ์ ศาสตราจารย์เจน " ) ;   

มีความซ้ำซ้อนเนื่องจากคำนำหน้า “อาจารย์วันดี” เหมือนกันในทั้งสองกรณี ตามความรู้ของฉัน ไม่มีคอมไพเลอร์ที่มีแนวโน้มว่าจะลดความซ้ำซ้อนนี้ อย่างไรก็ตาม คุณสามารถรับการตัดแต่งที่ต้องการได้โดยการทำลายสตริง:

 printf ( " สวัสดีครับอาจารย์ " ) ;       printf ( " โจนส์ " ) ;          printf ( " สวัสดีครับอาจารย์ " ) ;       printf ( " เจน " ) ;   

คอมไพเลอร์ส่วนใหญ่จะรู้จักสตริงคงที่และเก็บไว้ในโปรแกรมครั้งเดียว ใช้งานได้แม้ว่าสตริงคงที่ “Good day Professor” จะปรากฏในฟังก์ชันต่างๆ

ดังนั้นฟังก์ชันต่อไปนี้อาจคืนค่าเป็นจริง:

 const char * str1 = " เพื่อนรัก " ;       const char * str2 = " เพื่อนรัก " ;       กลับ str1 = = str2 ;   

นั่นคือ คุณไม่จำเป็นต้องสร้างสตริงคงที่ด้วยตนเอง: คอมไพเลอร์จะรับรู้ถึงความซ้ำซ้อน (โดยทั่วไป)

เคล็ดลับเดียวกันนี้ล้มเหลวด้วยสตริงที่ขยาย:

 const char * str1 = " เพื่อนรัก " ;       const char * str2 = " เพื่อนรัก \0 f " ;       กลับ str1 = = str2 ;   

คอมไพเลอร์ทั้งหมดที่ฉันพยายามคืนค่าเท็จ พวกเขาสร้างสตริง C สองสตริง แม้ว่าหนึ่งจะเป็นคำนำหน้าของอีกสตริงหนึ่งในตัวอย่างต่อไปนี้…

 ถ่าน get1 ( int k ) {       const char * str = " เพื่อนรัก " ;       กลับ str [ k ] ;   }      ถ่าน get2 ( int k ) {       const char * str = " เพื่อนรัก \0 f " ;       กลับ str [ k ] ;   }   

ไม่น่าแปลกใจเลยที่เคล็ดลับ “การบีบอัดข้อมูล” ใช้งานได้กับอาร์เรย์ ตัวอย่างเช่น อาร์เรย์ในฟังก์ชันทั้งสองนี้มีแนวโน้มที่จะคอมไพล์เป็นอาร์เรย์เดียว เนื่องจากคอมไพเลอร์รับรู้ว่าเหมือนกัน:

 int f ( int k ) {       int array [ ] = { 1 , 2 , 3 , 4 , 5 , 34432 , 321323 , 321321 , 1 ,       2 , 3 , 4 , 5 , 34432 , 321323 , 321321 } ;       กลับ อาร์เรย์ [ k ] ;   }         int g ( int k ) {       int array [ ] = { 1 , 2 , 3 , 4 , 5 , 34432 , 321323 , 321321 , 1 ,       2 , 3 , 4 , 5 , 34432 , 321323 , 321321 } ;       กลับ อาร์เรย์ [ k + 1 ] ;   }   

อาจยังคงใช้งานได้หากอาร์เรย์หนึ่งเป็นอาร์เรย์ย่อยที่แน่นอนของอาร์เรย์อื่นที่มี GCC ดังในตัวอย่างนี้:

 int f ( int k ) {       int array [ ] = { 1 , 2 , 3 , 4 , 5 , 34432 , 321323 , 321321 , 1 ,       2 , 3 , 4 , 5 , 34432 , 321323 , 321321 } ;       กลับ อาร์เรย์ [ k ] ;   }         int g ( int k ) {       int array [ ] = { 1 , 2 , 3 , 4 , 5 , 34432 , 321323 , 321321 , 1 ,       2 , 3 , 4 , 5 , 34432 , 321323 , 321321 , 1 , 4 } ;       กลับ อาร์เรย์ [ k + 1 ] ;   }   

มันยังใช้งานได้กับอาร์เรย์ของพอยน์เตอร์ เช่นในกรณีต่อไปนี้:

 อักขระ const * get1 ( int k ) {       const char * str [ ] = { " เพื่อนรัก " , " พี่สาวที่รัก " , " พี่ชายที่รัก " } ;       กลับ str [ k ] ;   }      อักขระ const * get2 ( int k ) {       const char * str [ ] = { " เพื่อนรัก " , " พี่สาวที่รัก " , " พี่ชายที่รัก " } ;       คืนค่า str [ k + 1 ] ;   }   

แน่นอน ถ้าคุณต้องการให้แน่ใจว่าโค้ดของคุณบางและมีประสิทธิภาพ คุณไม่ควรพึ่งพาคอมไพเลอร์อย่างสุ่มสี่สุ่มห้า อย่างไรก็ตาม ก็รับประกันว่าจะมองโลกในแง่ดีเล็กน้อย

ลิงค์วิทยาศาสตร์และเทคโนโลยี (16 กันยายน 2565)

ภาพบุคคล2018facebook.jpg

ลิงค์วิทยาศาสตร์และเทคโนโลยี (12 กันยายน 2565)

ภาพบุคคล2018facebook.jpg

  1. ชุดข้อมูลมาตรฐานในการวิจัยปัญญาประดิษฐ์มี ภาพติดป้ายกำกับผิด 10 เปอร์เซ็นต์ ทว่าอัลกอริธึมล้ำสมัยสามารถจำแนกประเภทได้ดีกว่า-90% ในชุดข้อมูลเดียวกัน (เครดิต: ลีโอ Boytsov)
  2. แม้จะมีค่ายฝึกซ้ำและการบาดเจ็บครั้งใหญ่ แต่ ครอบครัวที่ทำได้ดีก่อนการปฏิวัติสังคมนิยมจีนก็ยังทำได้ดี กล่าวอีกนัยหนึ่งเป็นการยากและอาจเป็นไปไม่ได้ที่จะขจัดความสามารถในการแข่งขันของบางครอบครัว
  3. การออกกำลังกายดูเหมือนจะช่วยเพิ่มฮิปโปแคมปัส (ในหนู) เพื่อให้การออกกำลังกายอาจเพิ่มการเรียนรู้เชิงพื้นที่
  4. ตะกั่วเป็นสารพิษที่อาจมีส่วนสำคัญในการก่ออาชญากรรมรุนแรง การใช้ตะกั่วอย่างระมัดระวังมากขึ้นจะอธิบายในส่วนของอาชญากรรมรุนแรงที่ลดลงเมื่อเวลาผ่าน ไป
  5. การดูวิดีโอที่ความเร็ว 2 เท่าสามารถเพิ่มความเร็วในการเรียนรู้ของคุณเป็นสองเท่า
  6. ชายคนหนึ่งที่ได้รับการปลูกถ่ายหัวใจจากหมูเสียชีวิตในสองเดือนต่อมา
  7. ความเร็วจิตไม่ได้ลดลงตามอายุอย่างที่เราคาดไว้: ไม่มีการสังเกตความเร็วจิตก่อนอายุ 60 ปี
  8. มาร์มอตดูเหมือนจะไม่แก่ในขณะที่พวกมันจำศีล
  9. มักกล่าวกันว่าฝาแฝดที่แยกออกจากกันมีความคล้ายคลึงกันอย่างโดดเด่นในด้านสติปัญญา และฝาแฝดที่แยกจากกันมีความคล้ายคลึงกันในหลาย ๆ ด้าน (เช่นบุคลิกภาพ) แต่ ความฉลาดของพวกเขาอาจเกี่ยวข้องน้อยกว่าที่เราคิด ไว้
  10. ปืนที่มีอยู่อย่างแพร่หลายทำให้การลงประชาทัณฑ์มีโอกาสน้อยลง
  11. อาหารเสริมวิตามินดีไม่ได้ช่วยป้องกันผู้สูงอายุจากการแตกหัก
  12. น้ำท่วมครั้งใหญ่ที่สุดในประวัติศาสตร์ของรัฐแคลิฟอร์เนียเกิดขึ้นในปี พ.ศ. 2405 น้ำท่วมหลังภัยแล้งยาวนานถึง 20 ปี และหุบเขากลายเป็นทะเลในช่วงเวลาสั้นๆ น้ำท่วมดังกล่าวดูเหมือนจะเกิดขึ้นค่อนข้างบ่อยแม้ว่าจะไม่มีน้ำท่วมใดเทียบได้ตั้งแต่นั้นเป็นต้นมา เห็นได้ชัดว่าชนพื้นเมืองอเมริกันรู้จักอุทกภัยเหล่านี้:

    ชนพื้นเมืองอเมริกันรู้ว่าหุบเขาแซคราเมนโตอาจกลายเป็นทะเลภายในเมื่อฝนตก นักเล่าเรื่องเล่าว่าน้ำเต็มหุบเขาตั้งแต่เทือกเขาโคสต์จนถึงเทือกเขาเซียร์รา

ตรวจจับข้อผิดพลาดของน้ำยาฆ่าเชื้อโดยทางโปรแกรม

ภาพบุคคล2018facebook.jpg

ภาษา C และ C++ มีการป้องกันข้อผิดพลาดของโปรแกรมเมอร์เพียงเล็กน้อย ข้อผิดพลาดไม่ได้แสดงขึ้นในที่ที่คุณคาดหวังเสมอไป คุณสามารถทำลายเนื้อหาในหน่วยความจำของคุณได้อย่างเงียบ ๆ มันสามารถทำให้บั๊กยากต่อการติดตาม เพื่อแก้ปัญหานี้ ฉันเป็นแฟนตัวยงของการเขียนโปรแกรมใน C และ C++ โดยใช้สารฆ่าเชื้อ มันทำให้โปรแกรมของคุณช้าลง แต่การตรวจสอบการเข้าถึงหน่วยความจำนั้นปลอดภัย เป็นต้น

ดังนั้น หากคุณวนซ้ำผ่านอาร์เรย์และเข้าถึงองค์ประกอบที่อยู่นอกขอบเขต โปรแกรมฆ่าเชื้อหน่วยความจำจะตรวจจับข้อผิดพลาดทันที:

 int อาร์เรย์ [ 8 ] ;     สำหรับ ( int k = 0 ; ; k + + ) {       อาร์เรย์ [ k ] = 0 ;     }   

น้ำยาฆ่าเชื้อรายงานข้อผิดพลาด แต่ถ้าคุณต้องการตรวจจับข้อผิดพลาดและเก็บไว้ในบันทึก โชคดีที่ตัวฆ่าเชื้อ GCC และ LLVM เรียกใช้ฟังก์ชัน ( __asan_on_error() ) เมื่อพบข้อผิดพลาด ทำให้เราบันทึกได้ แน่นอน คุณต้องบันทึกสถานะของโปรแกรมของคุณ ต่อไปนี้คือตัวอย่างที่บันทึกสถานะเป็นสตริง

 # รวม < iostream >   # รวม < สตริง >   # รวม < stdlib.h >      std :: ข้อความ สตริง ;      ภายนอก " C " {   เป็นโมฆะ __asan_on_error ( ) {     std :: cout < < " คุณทำให้เกิดข้อผิดพลาด: " < < ข้อความ < < std :: endl ;   }   }         int หลัก ( ) {     int อาร์เรย์ [ 8 ] ;     สำหรับ ( int k = 0 ; ; k + + ) {       message = std :: string ( " เข้าถึงที่ " ) + std :: to_string ( k ) ;       อาร์เรย์ [ k ] = 0 ;     }     ส่งคืน EXIT_SUCCESS ;   }   

นิพจน์ ภายนอก ทำให้แน่ใจว่า C ++ จะไม่ทำให้ชื่อฟังก์ชันเสียหาย

การเรียกใช้โปรแกรมนี้จะพิมพ์สิ่งต่อไปนี้:

   คุณทำให้เกิดข้อผิดพลาด: เข้าถึงที่ 8   

คุณสามารถเขียนไปยังไฟล์ได้หากต้องการ

ลิงค์วิทยาศาสตร์และเทคโนโลยี (7 สิงหาคม 2565)

ภาพบุคคล2018facebook.jpg

  1. ประสิทธิภาพการประมวลผลที่เพิ่มขึ้นอธิบายได้ถึง 94% ของการปรับปรุงประสิทธิภาพในด้านต่างๆ เช่น การทำนายสภาพอากาศ การพับของโปรตีน และการสำรวจน้ำมัน : เทคโนโลยีสารสนเทศเป็นตัวขับเคลื่อนของการปรับปรุงประสิทธิภาพในระยะยาวในสังคม หากเราหยุดปรับปรุงการประมวลผลของเรา ผลที่ตามมาอาจเลวร้าย
  2. ปะการังที่ปกคลุมแนวปะการัง Great Barrier Reef ได้ ถึงระดับสูงสุดนับตั้งแต่สถาบันวิทยาศาสตร์ทางทะเลแห่งออสเตรเลีย (AIMS) เริ่มเฝ้าติดตามเมื่อ 36 ปีก่อน
  3. ทฤษฎีชั้นนำของอัลไซเมอร์ สมมติฐานเกี่ยวกับอะไมลอยด์ ซึ่งกระตุ้นการวิจัยเป็นเวลาหลายปี ถูกสร้างขึ้นส่วนหนึ่งจากการฉ้อโกง ผู้เขียนการฉ้อโกงคือศาสตราจารย์ Sylvain Lesné ดูเหมือน ว่าทีมของเขาจะประกอบร่างโดยนำภาพถ่ายจากการทดลองต่างๆ มาปะติดปะต่อกัน อย่างมีประสิทธิภาพ พวกเขา “photoshopped” เอกสารทางวิทยาศาสตร์ของพวกเขา ไม่ใช่แค่ภาพเดียวหรือสองภาพ แต่อย่างน้อย 70 ภาพ โปรดทราบว่าการทดลองทางคลินิกทั้งหมดของยาที่พัฒนาขึ้น (ด้วยราคาสูง) บนสมมติฐานอะไมลอยด์ล้มเหลว ค่าใช้จ่ายทั้งหมดอยู่ในพันล้านดอลลาร์ ในขณะเดียวกัน ทฤษฎีและการรักษาที่แข่งขันกันถูกกีดกันโดยสมมติฐานอะไมลอยด์ที่น่าสนใจ น่าสนใจที่จะดูบทลงโทษแบบใด หากมี เลสเน่ได้รับจากการกระทำของเขา คุณอาจอ่านคำให้การของนักวิจัยที่ทำงานยากเพราะพวกเขาไม่เชื่อในสมมติฐานอะไมลอยด์ เช่น เรื่องราวที่น่าคลั่งไคล้ว่า ‘cabal’ ของโรคอัลไซเมอร์ขัดขวางความก้าวหน้าในการรักษามานานหลายทศวรรษ (ตั้งแต่ปี 2019) หรือ เรื่องราวของ Rachael Neve ผลสุทธิ? ไม่มีความคืบหน้าแม้จะมีเงินทุนจำนวนมาก:

    ในช่วง 30 (ปัจจุบัน 35) ปีที่นักวิจัยด้านชีวการแพทย์ได้ทำงานอย่างมุ่งมั่นเพื่อหาวิธีรักษาโรคอัลไซเมอร์ เพื่อนร่วมงานของพวกเขาได้พัฒนายาที่ช่วยลดการเสียชีวิตจากโรคหัวใจและหลอดเลือดได้มากกว่าครึ่งหนึ่ง และยารักษามะเร็งสามารถกำจัดเนื้องอกที่รักษาไม่หาย . แต่สำหรับโรคอัลไซเมอร์ ไม่เพียงแต่ไม่มีทางรักษา ไม่มีแม้แต่การรักษาที่ชะลอการเกิดโรคอีกด้วย

    เรามี การวิจัยเกี่ยวกับโรคอัลไซเมอร์เป็นเวลาสองทศวรรษ โดยส่วนหนึ่งมาจากการฉ้อโกงโดยเจตนา ซึ่งอาจมีค่าใช้จ่ายหลายล้านชีวิต

  4. เป็นเวลาหลายปีแล้วที่เราได้รับแจ้งว่าภาวะซึมเศร้าเกิดจากความไม่สมดุลของสารเคมีในสมอง โดยเฉพาะระดับเซโรโทนินที่ต่ำ เริ่มแรกเสนอให้ยาต้านอาการซึมเศร้าทำงานโดยแก้ไขความผิดปกติของเซโรโทนิน บทความใหม่ที่ตีพิมพ์โดย Nature แสดงให้เห็นว่าคนที่เป็นโรคซึมเศร้าไม่ได้มีระดับ serotonin ที่ต่ำกว่าเท่านั้น แต่ยิ่งไปกว่านั้น การใช้ยากล่อมประสาทในระยะยาวอาจทำให้ระดับ serotonin ลดลงได้
  5. วิทยาศาสตร์ได้รับการ ‘โควิด’ :

    ในสาขาวิทยาศาสตร์ 98 แห่งจาก 100 เอกสารที่ตีพิมพ์มากที่สุดในปี 2020 ถึง 2021 เกี่ยวข้องกับ COVID-19 นักวิทยาศาสตร์จำนวนมากได้รับการอ้างอิงงานเกี่ยวกับโควิด-19 เป็นจำนวนมาก ซึ่งมักจะเกินการอ้างอิงที่พวกเขาได้รับจากงานทั้งหมดตลอดอาชีพการทำงาน

  6. โลกกำลังเป็นมิตรกับสิ่งแวดล้อมมากขึ้นเนื่องจากการมีอยู่ของ CO2 ในชั้นบรรยากาศที่เพิ่มขึ้น และคาดว่าจะนำไปสู่การเย็นลงอย่างมากตาม บทความใน Nature
  7. ทะเลทรายซาฮาร่าเป็นสีเขียวตั้งแต่ 14,000 ถึง 5,000 ปีก่อน นักวิจัยบางคนเชื่อว่ามันกลายเป็นทะเลทรายเนื่องจากการเย็นตัวของมหาสมุทรแอตแลนติกอย่างกะทันหัน

เปรียบเทียบ strtod กับ from_chars (GCC 12)

ผู้อ่าน (Richard Ebeling) เชิญให้ฉันทบทวนบล็อกโพสต์ที่เก่ากว่า: Parsing floats in C++: การเปรียบเทียบ strtod vs. from_chars ย้อนกลับไปแล้ว ฉันรายงานว่าการเปลี่ยนจาก strtod เป็น from_chars ใน C++ เป็นหมายเลขการแยกวิเคราะห์อาจทำให้ความเร็วเพิ่มขึ้น (เพิ่มขึ้น 20%) รหัสเหมือนกันมาก เราไปจาก…

 ถ่าน * string = " 3.1416 " ; ถ่าน * string_end = สตริง ; double x = strtod ( สตริง , & string_end ) ; ถ้า ( string_end = = สตริง ) {    // คุณมีข้อผิดพลาด! } 

… สู่ความทันสมัยใน C++17…

 std :: สตริง st = " 3.1416 " ; สองเท่า x ;  อัตโนมัติ [ p , ec ] = std :: from_chars ( st . data ( ) , st . data ( ) + st . ขนาด ( ) , x ) ; ถ้า ( p = = st . data ( ) ) {       // คุณมีข้อผิดพลาด s! } 

ย้อนกลับไปเมื่อฉันรายงานผลลัพธ์นี้ครั้งแรก มีเพียง Visual Studio เท่านั้นที่รองรับ from_chars ขณะนี้ไลบรารี C++ ใน GCC 12 รองรับ from_chars อย่างเต็มรูปแบบแล้ว ให้เราเรียกใช้การวัดประสิทธิภาพอีกครั้ง :

strtod 270 MB/วินาที
from_chars 1 GB/วินาที

เร็วกว่าเกือบสี่เท่า! เกณฑ์มาตรฐานจะอ่านค่าแบบสุ่มในช่วง [0,1]

ภายใน GCC 12 นำ ไลบรารี fast_float มาใช้

อ่านเพิ่มเติม : Number Parsing at a Gigabyte per Second , Software: Pratice and Experience 51 (8), 2021.

ปัดเศษเวกเตอร์ทิศทางเป็นเข็มทิศ 8 ทิศทาง

ภาพบุคคล2018facebook.jpg

ตัวควบคุมเกมสมัยใหม่สามารถชี้ไปในทิศทางที่หลากหลาย บางครั้งนักออกแบบเกมต้องการ เปลี่ยนทิศทางของจอยสติ๊กเพื่อให้ได้การเคลื่อนไหว 8 ทิศทาง วิธีแก้ปัญหาทั่วไปที่นำเสนอคือการคำนวณมุม ปัดเศษขึ้น แล้วคำนวณเวกเตอร์ทิศทางกลับ

 มุม คู่ = atan2 ( y , x ) ;  
   
  มุม = ( int ( รอบ ( 4 * มุม / PI + 8 ) ) % 8 ) * PI / 4 ;  
   
  xout = cos ( มุม ) ;  
   
  yout = บาป ( มุม ) ;  
   

หากคุณถือว่าเวกเตอร์ทิศทางอยู่ในจตุภาคแรก (ทั้ง x และ y เป็นบวก) แสดงว่ามีวิธีคำนวณคำตอบโดยตรง ใช้ 1/sqrt(2) หรือ 0.7071 เป็นโซลูชันเริ่มต้น เปรียบเทียบทั้ง x และ y กับ cos(3*pi/8) และ cos(pi/8) และเปลี่ยนเป็น 1 หรือ 0 หากมีค่ามากกว่า cos เท่านั้น (3*pi/8) หรือเล็กกว่า cos(pi/8) รหัสเต็มมีลักษณะดังนี้:

 xout = 0.7071067811865475 ;  
   
  คุณ = 0.7071067811865475 ;  
   
  
   
  ถ้า ( x > = 0.923879532511286 ) { // cos(3*pi/8)  
   
    xout = 1 ;  
   
  }  
   
  ถ้า ( y > = 0.923879532511286 ) { // cos(3*pi/8)  
   
    คุณ = 1 ;  
   
  }  
   
  ถ้า ( x < 0.3826834323650898 ) { // cos (pi/8)  
   
    xout = 0 ;  
   
  }  
   
  ถ้า ( y < 0.3826834323650898 ) { // cos (pi/8)  
   
    คุณ = 0 ;  
   
  }  
   

คุณสามารถสรุปวิธีแก้ปัญหาสำหรับกรณีที่ x หรือ y (หรือทั้งสองอย่าง) เป็นลบโดยเอาค่าสัมบูรณ์ก่อนแล้วจึงคืนค่าเครื่องหมายในตอนท้าย:

 บูล xneg = x < 0 ;  
   
  บูลเน็ก = y < 0 ;  
   
  ถ้า ( xneg ) {  
   
    x = - x ;  
   
  }  
   
  ถ้า ( เหน ) {  
   
    y = - y ;  
   
  }  
   
  outx สองเท่า = 0.7071067811865475 ;  
   
  ดับเบิ้ล = 0.7071067811865475 ;  
   
  
   
  ถ้า ( x > = 0.923879532511286 ) { // cos(3*pi/8)  
   
    outx = 1 ;  
   
  }  
   
  ถ้า ( y > = 0.923879532511286 ) { // cos(3*pi/8)  
   
    นอก = 1 ;  
   
  }  
   
  ถ้า ( x < 0.3826834323650898 ) { // cos (pi/8)  
   
    outx = 0 ;  
   
  }  
   
  ถ้า ( y < 0.3826834323650898 ) { // cos (pi/8)  
   
    นอก = 0 ;  
   
  }  
   
  ถ้า ( xneg ) {  
   
    outx = - outx ;  
   
  }  
   
  ถ้า ( เหน ) {  
   
    outy = - outy ;  
   
  }  
   

ฉันเขียนเกณฑ์มาตรฐานขนาดเล็กที่ทำงานบนอินพุตแบบสุ่ม ผลลัพธ์ของคุณจะแตกต่างกันไป แต่ในแล็ปท็อป Mac ของฉันที่มี LLVM 12 ฉันเข้าใจว่าวิธีการโดยตรงนั้นเร็วกว่า 25 เท่า

ด้วยแทนเจนต์ 40 ns/เวกเตอร์
วิธีที่รวดเร็ว 1.5 ns/เวกเตอร์

ลิงค์วิทยาศาสตร์และเทคโนโลยี (23 กรกฎาคม 2565)

ภาพบุคคล2018facebook.jpg

    1. เมื่อเทียบกับปี 1800 เรากินไขมันอิ่มตัวน้อยลง อาหารแปรรูปและน้ำมันพืชมากกว่า และดูเหมือนจะไม่ดีสำหรับเรา:

      ไขมันอิ่มตัวจากแหล่งสัตว์ลดลงในขณะที่ไขมันไม่อิ่มตัวเชิงซ้อนจากน้ำมันพืชเพิ่มขึ้น โรคไม่ติดต่อ (NCDs) เพิ่มขึ้นในศตวรรษที่ 20 ควบคู่ไปกับการบริโภคอาหารแปรรูปที่เพิ่มขึ้น ซึ่งรวมถึงน้ำตาล แป้งกลั่นและข้าว และน้ำมันพืช ไขมันอิ่มตัวจากสัตว์มีความสัมพันธ์ผกผันกับความชุกของโรคไม่ติดต่อ

      คัง et al. พบว่าไขมันอิ่มตัวลดความเสี่ยงของการเป็นโรคหลอดเลือดสมอง:

      การบริโภคอาหารที่มีไขมันอิ่มตัวสูงนั้นสัมพันธ์กับความเสี่ยงที่ลดลงของโรคหลอดเลือดสมอง และทุกๆ 10 กรัม/วันของการบริโภคไขมันอิ่มตัวที่เพิ่มขึ้นนั้นสัมพันธ์กับการลดความเสี่ยงที่สัมพันธ์กัน 6% ของอัตราการเกิดโรคหลอดเลือดสมอง

      ไขมันอิ่มตัวมาจากเนื้อสัตว์และผลิตภัณฑ์จากนม (เช่น เนย) การรับประทานอาหารที่มีไขมันต่ำสามารถเพิ่มความเสี่ยงของการเกิดโรคหลอดเลือดหัวใจได้อย่างมีนัยสำคัญ
      Leroy และ Cofnas โต้เถียงกับการลดการบริโภคเนื้อแดง:

      IARC’s (2015) อ้างว่าเนื้อแดง “อาจเป็นสารก่อมะเร็ง” ไม่เคยได้รับการพิสูจน์มาก่อน อันที่จริง การประเมินความเสี่ยงโดยครูเกอร์และโจว (2018) สรุปว่าไม่เป็นเช่นนั้น (…) การวิเคราะห์เมตาของ RCT แสดงให้เห็นว่าการกินเนื้อสัตว์ไม่ได้นำไปสู่การเสื่อมสภาพของตัวบ่งชี้ความเสี่ยงโรคหัวใจและหลอดเลือด (O’Connor et al., 2017) หมวดที่กินเนื้อสัตว์สูงที่สุดนั้นควบคู่ไปกับการเพิ่มขึ้นของระดับ HDL-C ที่อาจเป็นประโยชน์ ในขณะที่อาหารที่เน้นพืชเป็นหลักดูเหมือนจะลดโคเลสเตอรอลรวมและ LDL-C ในการศึกษาการแทรกแซง พวกเขายังเพิ่มระดับไตรกลีเซอไรด์และลด HDL-C (Yokoyama et al., 2017) ซึ่งปัจจุบันมักถูกมองว่าเป็นตัวบ่งชี้ที่เหนือกว่าของความเสี่ยงโรคหัวใจและหลอดเลือด ( Jeppesen et al., 2001). (…) เราเชื่อว่าการบริโภคเนื้อสัตว์ที่ลดลงอย่างมาก เช่น ได้รับการสนับสนุนจากคณะกรรมาธิการ EAT-Lancet (Willett et al., 2019) อาจก่อให้เกิดอันตรายร้ายแรงได้ เนื้อสัตว์เป็นแหล่งโภชนาการคุณภาพสูงมาช้านานและยังคงดำเนินต่อไป ทฤษฎีที่ว่าพืชตระกูลถั่วและอาหารเสริมสามารถถูกแทนที่ได้เป็นเพียงการเก็งกำไร ในขณะที่อาหารที่มีเนื้อสัตว์สูงได้รับการพิสูจน์แล้วว่าประสบผลสำเร็จตลอดประวัติศาสตร์อันยาวนานของสายพันธุ์ของเรา ประโยชน์ของอาหารมังสวิรัตินั้นยังห่างไกลจากการเป็นที่ยอมรับ และผู้ที่รับรองก่อนเวลาอันควรเนื่องจากหลักฐานที่น่าสงสัยส่วนใหญ่ละเลยอันตรายของอาหารเหล่านี้

    2. ผู้คนไม่ชอบงานวิจัยที่ดูเหมือนชอบผู้ชาย :

      ในการศึกษาทั้งสอง ทั้งสองเพศมีปฏิกิริยาในเชิงบวกน้อยลงต่อความแตกต่างที่ชื่นชอบผู้ชาย ตรงกันข้ามกับการวิจัยก่อนหน้านี้ของเรา อย่างไรก็ตาม ผลที่ได้นั้นมากกว่าในหมู่ผู้เข้าร่วมเพศหญิง ตรงกันข้ามกับความคาดหวังที่แพร่หลาย ผู้เข้าร่วมไม่ได้ตอบสนองในเชิงบวกน้อยลงต่อการวิจัยที่นำโดยผู้หญิง ผู้เข้าร่วมการวิจัยมีปฏิกิริยาในเชิงบวกน้อยลง ต่อการวิจัยที่นำโดยผู้ชายเมื่อการวิจัยรายงานความแตกต่างที่ผู้ชายชื่นชอบในลักษณะที่มีมูลค่าสูง ผู้เข้าร่วมประเมินว่างานวิจัยที่ถูกใจผู้ชายนั้นมีคุณภาพต่ำกว่างานวิจัยที่ถูกใจผู้หญิง ซึ่งส่วนใหญ่เห็นได้ชัดเพราะพวกเขามองว่าการวิจัยแบบเดิมนั้นเป็นอันตรายมากกว่า

    3. ในช่วงยุคจูราสสิก คาร์บอนไดออกไซด์ในชั้นบรรยากาศสูงมาก ป่าไม้แผ่ขยายไปจนถึงขั้วโลกเหนือ ถึงกระนั้นก็มีฤดูหนาวที่หนาวเหน็บ :

      ป่าไม้มีอยู่ตลอดทางจนถึงขั้วโลกเหนือของแพงเจียน และเข้าไปในละติจูดใต้สุดเท่าที่แผ่นดินขยายออกไป แม้ว่าอาจมีปัจจัยสนับสนุนอื่น ๆ แต่สมมติฐานชั้นนำก็คือโลกอยู่ในสถานะ “เรือนกระจก” เนื่องจากมี PCO2 ในชั้นบรรยากาศที่สูงมาก (ความดันบางส่วนของ CO2) ซึ่งสูงที่สุดในรอบ 420 ล้านปีที่ผ่านมา แม้ว่าผลการสร้างแบบจำลองจะบ่งชี้ว่าอุณหภูมิในฤดูหนาวเยือกแข็งที่ละติจูดสูง แต่ยังไม่มีหลักฐานเชิงประจักษ์สำหรับการแช่แข็ง ในที่นี้ เราให้หลักฐานเชิงประจักษ์ที่แสดงให้เห็นว่า แม้จะมี PCO2 ที่สูงเป็นพิเศษ แต่อุณหภูมิเยือกแข็งในฤดูหนาวก็แสดงให้เห็นลักษณะละติจูดของ Pangean ที่สูงโดยอิงจากเศษซากที่ล่องแก่งด้วยน้ำแข็งในทะเลสาบ (L-IRD) ที่แพร่หลายในชั้นหินในชั้นหินมีโซโซอิกช่วงต้นของลุ่มน้ำ Junggar ทางตะวันตกเฉียงเหนือของจีน ตามเนื้อผ้า ไดโนเสาร์ถูกมองว่าเฟื่องฟูในภูมิอากาศแบบมีโซโซอิกช่วงต้นที่อบอุ่นและเท่าเทียมกัน แต่ผลลัพธ์ของเราบ่งชี้ว่าพวกมันสามารถทนต่อฤดูหนาวที่หนาวเหน็บได้เช่นกัน

    4. ในหนูทดลอง นักวิจัยพบ ว่าการฉีด ” สื่อที่ปรับสภาพ ” ที่ได้จากสเต็มเซลล์ช่วยป้องกันการเสื่อมของระบบประสาท:

      การตายของเซลล์ประสาทมีสาเหตุมาจากโรคทางระบบประสาทหลายชนิด รวมถึงการสูญเสียความจำและภาวะสมองเสื่อมที่เกี่ยวข้องกับอายุ (เช่น โรคอัลไซเมอร์) โรคพาร์กินสัน โรคหลอดเลือดสมอง และโรคที่ส่งผลกระทบต่อวัยทั่วไป เช่น การบาดเจ็บที่สมอง การบาดเจ็บที่ไขสันหลัง ALS และกล้ามเนื้อลีบกระดูกสันหลัง โรคเหล่านี้มีลักษณะเฉพาะจากการอักเสบของเส้นประสาทและความเสียหายของเซลล์ออกซิเดชัน หลายชนิดเกี่ยวข้องกับโปรตีโอสตาซิสที่ถูกรบกวน ซึ่งล้วนแต่ทำลายล้างและไม่มีวิธีรักษา งานของเราอธิบายถึงการรักษาโรค ALS ที่มีความหมายที่เป็นไปได้ให้น้อยที่สุด และแสดงให้เห็นความสามารถทางคลินิกในการรักษาโรคต่างๆ ที่เกี่ยวข้องกับการเสื่อมสภาพของระบบประสาท และการตายของเซลล์ที่มากเกินไป

    5. กรีนแลนด์และทางเหนือของยุโรปเคยอบอุ่นกว่าในทุกวันนี้: ยุคอบอุ่น ในยุคกลาง (950 ถึง 1250) ซ้อนทับกับยุคไวกิ้ง (800–1300) Bajard และคณะ (2022) เสนอว่าไวกิ้งค่อนข้างเชี่ยวชาญในการปรับวิธีปฏิบัติทางการเกษตรของตน:

      (…) ช่วงเวลาตั้งแต่ยุคไวกิ้งจนถึงยุคกลางสูงเป็นช่วงเวลาของการขยายตัวพร้อมกับชาวไวกิ้งพลัดถิ่น เพิ่มการค้า การผลิตอาหารและสินค้า และการก่อตั้งเมืองสแกนดิเนเวีย ช่วงเวลานี้ยังเห็นการเพิ่มขึ้นอย่างรวดเร็วของประชากรและการตั้งถิ่นฐาน สาเหตุหลักมาจากสภาพอากาศที่อบอุ่นค่อนข้างคงที่ (…) เป็นปัจจัยขับเคลื่อนหลักในการปฏิบัติทางการเกษตรในนอร์เวย์ตะวันออกเฉียงใต้ในสมัยโบราณตอนปลาย การเปรียบเทียบโดยตรงระหว่างความแปรปรวนของอุณหภูมิที่สร้างขึ้นใหม่และข้อมูล palynological จากลำดับตะกอนเดียวกันแสดงให้เห็นว่าการเปลี่ยนแปลงเล็กน้อยของอุณหภูมิสอดคล้องกับการเปลี่ยนแปลงในการเกษตร (…) เราสรุปได้ว่าสังคมยุคก่อนยุคไวกิ้งในสแกนดิเนเวียตะวันตกเฉียงใต้ได้ทำการเปลี่ยนแปลงอย่างมากในแนวทางของพวกเขา การใช้ชีวิตเพื่อปรับตัวให้เข้ากับสภาพอากาศแปรปรวนในช่วงนี้

      ชาวไวกิ้งปลูกข้าวบาร์เลย์และข้าวโพดในกรีนแลนด์ ในทางตรงกันข้าม เกษตรกรรมในกรีนแลนด์ในปัจจุบันแทบไม่มีเลยเนื่องจากสภาพอากาศที่เลวร้าย

    6. หน่วยสืบราชการลับของอาซเกนาซีมักจะทำคะแนนได้ดีเป็นพิเศษในการทดสอบสติปัญญา และพวกเขาบรรลุผลลัพธ์ที่ไม่ธรรมดาในการแสวงหาทางปัญญาหลายอย่าง
      อย่างไรก็ตาม บรรณาธิการวิกิพีเดียได้ลบบทความเกี่ยวกับข่าวกรองอาซเกนาซี Tezuka โต้แย้งว่าเป็น ผลมาจากอคติทางอุดมการณ์ ที่ส่งผลให้เกิดการเซ็นเซอร์อย่างเป็นระบบ
    7. คุณสามารถชุบตัวผิวหนังคนแก่ได้ด้วยการทาบลงบนหนูตัว น้อย
    8. Tabarrok เตือนเราว่าทุนวิจัยผ่านการแข่งขัน อาจส่งผลให้เกิดการสูญเสียทั้งหมดจากการกระจายค่าเช่า …

      นักวิทยาศาสตร์ที่ได้รับประโยชน์จากเงินช่วยเหลือ NIH มูลค่า 2 ล้านดอลลาร์ เต็มใจที่จะใช้เวลาหนึ่งล้านดอลลาร์ไปกับการทำงานกับแอปพลิเคชัน หรือต้องเสียค่าใช้จ่ายในการจำกัดแนวคิดการวิจัยเพื่อให้ได้มา ที่สำคัญ แม้ว่าจะมีนักวิทยาศาสตร์เพียงคนเดียวเท่านั้นที่จะได้รับทุน แต่นักวิทยาศาสตร์หลายร้อยคนก็ใช้ทรัพยากรในการแข่งขันเพื่อให้ได้มา ดังนั้น ประโยชน์ที่เราอาจได้รับจากการถ่ายโอนทรัพยากรไปยังนักวิจัยคนหนึ่งจึงกระจายไปทวีคูณในนักวิทยาศาสตร์ทุกคนที่ใช้เวลาและเงินแข่งขันกันเพื่อขอรับทุนแต่ไม่ได้รับ เวลาโดยรวมที่ใช้สำหรับความคิดที่เฉียบแหลมที่สุดของเราจากระบบการแข่งขันแอปพลิเคชันนี้มีขนาดใหญ่พอสมควร ซึ่งอาจหักล้างมูลค่าทางวิทยาศาสตร์ทั้งหมดของการวิจัยที่เงินทุนสนับสนุนได้ทั้งหมด

    9. การลดภาษีนิติบุคคลนำไปสู่การเพิ่มผลผลิตและการวิจัยในระยะยาว ในทางกลับกัน การเพิ่มขึ้นของการเก็บภาษีจะลดประสิทธิภาพการทำงานในระยะยาว เช่นเดียวกับการวิจัยและพัฒนา

คุณสามารถแปลงโฟลตเป็นสองเท่า (และย้อนกลับ) ได้เร็วแค่ไหน?

ภาษาโปรแกรมหลายภาษามีเลขทศนิยมสองประเภท: float (32 บิต) และคู่ (64 บิต) สะท้อนให้เห็นถึงความจริงที่ว่าโปรเซสเซอร์ที่ใช้งานทั่วไปส่วนใหญ่รองรับข้อมูลทั้งสองประเภทโดยกำเนิด

บ่อยครั้งที่เราต้องแปลงระหว่างสองประเภท โปรเซสเซอร์ทั้ง ARM และ x64 สามารถทำได้ในคำสั่งเดียวราคาไม่แพง ตัวอย่างเช่น ระบบ ARM อาจใช้คำสั่ง fcvt

รายละเอียดอาจแตกต่างกัน แต่โปรเซสเซอร์ปัจจุบันส่วนใหญ่สามารถแปลงตัวเลขได้หนึ่งหมายเลข (จาก float เป็น double หรือจาก double เป็น float) ต่อรอบ CPU เวลาแฝงมีขนาดเล็ก (เช่น 3 หรือ 4 รอบ)

โปรเซสเซอร์ทั่วไปอาจทำงานที่ 3 GHz ดังนั้นเราจึงมี 3 พันล้านรอบต่อวินาที ดังนั้นเราสามารถแปลงตัวเลข 3 พันล้านต่อวินาที หมายเลข 64 บิตใช้ 8 ไบต์ ดังนั้นจึงมีอัตราความเร็ว 24 ไบต์ต่อวินาที

ดังนั้นจึงไม่น่าเป็นไปได้ที่การแปลงประเภทจะเป็นคอขวดของประสิทธิภาพโดยทั่วไป หากคุณต้องการวัดความเร็วในระบบของคุณเอง: ฉันได้เขียนเกณฑ์มาตรฐาน C++ ขนาดเล็ก

กรองตัวเลขได้เร็วขึ้นด้วย SVE บนโปรเซสเซอร์ Amazon Graviton 3

ภาพบุคคล2018facebook.jpg

โปรเซสเซอร์มาในตระกูลใหญ่สองตระกูล x64 โปรเซสเซอร์จาก Intel และ AMD และโปรเซสเซอร์ ARM จาก Apple, Samsung และผู้จำหน่ายรายอื่น ๆ เป็นเวลานาน โปรเซสเซอร์ ARM ครอบครองตลาดของโปรเซสเซอร์แบบฝังเป็นส่วนใหญ่ (คอมพิวเตอร์ที่ใช้งานตู้เย็นของคุณที่บ้าน) โดยที่ ‘โปรเซสเซอร์ขนาดใหญ่’ เป็นโดเมนของโปรเซสเซอร์ x64 เท่านั้น

มีรายงานว่า CEO ของ Apple (Steve Jobs) ได้ไปพบ Intel ย้อนกลับไปเมื่อ Apple กำลังออกแบบ iPhone เพื่อขอข้อตกลงโปรเซสเซอร์ Intel ปฏิเสธ Apple ดังนั้น Apple จึงเลือกใช้ ARM

ทุกวันนี้ เราใช้โปรเซสเซอร์ ARM สำหรับทุกสิ่ง: เกมคอนโซล (Nintendo Switch), เซิร์ฟเวอร์ที่ทรงพลัง (Amazon และ Google), โทรศัพท์มือถือ, อุปกรณ์ฝังตัว และอื่นๆ

Amazon เปิดตัวโปรเซสเซอร์ที่ใช้ ARM รุ่นใหม่ (Graviton 3) โปรเซสเซอร์เหล่านี้มีคำสั่ง SIMD ที่ซับซ้อน (SIMD ย่อมาจาก Single Instruction Multiple Data) ที่เรียกว่า SVE (Scalable Vector Extensions) ด้วยคำแนะนำเหล่านี้ เราสามารถเร่งความเร็วซอฟต์แวร์ได้อย่างมาก เป็นรูปแบบหนึ่งของ single-core parallelism เมื่อเทียบกับความขนานที่ได้รับโดยใช้หลายคอร์สำหรับหนึ่งงาน เมื่อนำไปใช้ได้ SIMD parallelism มักจะมีประสิทธิภาพมากกว่า multicore parallelism

Graviton 3 ของ Amazon ดูเหมือนจะมีการลงทะเบียน 32 ไบต์ เนื่องจากดีที่สุดสำหรับการ ออกแบบ ARM Neoverse V1 คุณสามารถใส่จำนวนเต็ม 32 บิตแปดตัวในการลงทะเบียนเดียว โปรเซสเซอร์ ARM หลัก (เช่นตัวที่ Intel ใช้) มีคำสั่ง SIMD ด้วย (NEON) แต่มีการลงทะเบียนที่สั้นกว่า (16 ไบต์) การมีรีจิสเตอร์และคำสั่งที่กว้างขึ้นซึ่งสามารถทำงานได้บนรีจิสเตอร์แบบกว้างเหล่านี้ ช่วยให้คุณลดจำนวนคำสั่งทั้งหมดได้ การรันคำสั่งน้อยลงเป็นวิธีที่ดีมากในการเร่งโค้ด

ในการตรวจสอบ SVE ฉันได้พิจารณาปัญหาง่ายๆ ที่คุณต้องการลบจำนวนเต็มลบทั้งหมดออกจากอาร์เรย์ นั่นคือ คุณอ่านและอาร์เรย์ที่มีจำนวนเต็มสุ่มที่ลงนามแล้ว และคุณต้องการเขียนลงในอาร์เรย์เอาต์พุตเฉพาะจำนวนเต็มบวกเท่านั้น รหัส C ปกติอาจมีลักษณะดังนี้:

 เป็นโมฆะ remove_negatives_scalar ( อินพุต const int32_t *           จำนวน int64_t , int32_t * เอาต์พุต ) {    int64_t ผม = 0 ;    int64_t j = 0 ;    สำหรับ ( ; ผม < นับ ; ผม + + ) {      ถ้า ( ป้อน [ i ] > = 0 ) {        เอาท์พุต [ j + + ] = อินพุต [ i ] ;      }    }  }  

การแทนที่โค้ดนี้ด้วยโค้ดใหม่ที่อาศัยฟังก์ชัน SVE พิเศษ ทำให้ใช้งานได้เร็วขึ้นมาก (เร็วขึ้น 2.5 เท่า) ในขณะนั้น ฉันแนะนำว่าโค้ดของฉันอาจไม่ค่อยเหมาะสมที่สุด มันประมวลผล 32 ไบต์ต่อการวนซ้ำโดยใช้ 9 คำแนะนำ ส่วนที่ใหญ่มากของคำแนะนำทั้ง 9 ข้อนี้เกี่ยวข้องกับการจัดการลูป และมีเพียงไม่กี่คำเท่านั้นที่ทำการกระทืบตัวเลขจริง ผู้อ่านชื่อ Samuel Lee เสนอให้คลายลูปของฉันอย่างมีประสิทธิภาพ เขาคาดการณ์ถึงประสิทธิภาพที่ดีขึ้นมาก (อย่างน้อยเมื่ออาร์เรย์มีขนาดใหญ่พอ) เนื่องจากโอเวอร์เฮดของลูปที่ต่ำกว่า ฉันรวมรหัสที่เขาเสนอไว้ด้านล่าง

เมื่อใช้โปรเซสเซอร์ graviton 3 และ GCC 11 ในเกณฑ์มาตรฐาน ฉันได้ผลลัพธ์ดังต่อไปนี้:

รอบ/int instr./int instr./cycle
สเกลาร์ 9.0 6.000 0.7
สเกลาร์ไร้แขนง 1.8 8.000 4.4
SVE 0.7 1.125 ~1.6
คลี่ SVE 0.4385 0.71962 ~1.6

โค้ด SVE ที่คลายใหม่ใช้คำสั่ง 23 คำสั่งในการประมวลผล 128 ไบต์ (หรือจำนวนเต็ม 32 บิต 32 บิต) ดังนั้นประมาณ 0.71875 คำสั่งต่อจำนวนเต็ม นั่นคือคำสั่งที่น้อยกว่าโค้ดสเกลาร์ประมาณ 10 เท่า และเร็วกว่าโค้ดสเกลาร์ประมาณ 4 เท่าในแง่ของรอบของ CPU

จำนวนคำสั่งที่เลิกใช้ต่อรอบจะใกล้เคียงกันสำหรับฟังก์ชัน SVE สองฟังก์ชัน และค่อนข้างต่ำ ซึ่งค่อนข้างสูงกว่า 1.5 คำสั่งที่เลิกใช้ต่อรอบ

บ่อยครั้งข้อโต้แย้งที่สนับสนุน SVE คือไม่ต้องใช้รหัสพิเศษเพื่อสิ้นสุดการประมวลผลส่วนท้าย นั่นคือ คุณสามารถประมวลผลอาร์เรย์ทั้งหมดได้โดยใช้คำสั่ง SVE แม้ว่าความยาวของอาร์เรย์จะไม่ถูกหารด้วยขนาดรีจิสเตอร์ (ที่นี่มี 8 จำนวนเต็ม) ฉันพบว่าโค้ดของ Lee น่าสนใจ เพราะมันแสดงให้เห็นว่าจริง ๆ แล้วคุณอาจต้องจัดการกับส่วนท้ายของ long array ให้แตกต่างออกไป ด้วยเหตุผลด้านประสิทธิภาพ

โดยรวมแล้ว ฉันคิดว่าเราจะเห็นว่า SVE ทำงานได้ดีสำหรับปัญหาที่มีอยู่ (การกรองจำนวนเต็ม 32 บิตออก)

ภาคผนวก : รหัสของซามูเอล ลี

 เป็นโมฆะ remove_negatives ( อินพุต const int32_t * , จำนวน int64_t , เอาต์พุต int32_t * ) {    int64_t j = 0 ;    const int32_t * endPtr = อินพุต + นับ ;    const uint64_t vl_u32 = svcntw ( ) ;      svbool_t all_mask = svptrue_b32 ( ) ;    ในขณะที่ ( อินพุต < = endPtr - ( 4 * vl_u32 ) )    {        svint32_t in0 = svld1_s32 ( all_mask , อินพุต + 0 * vl_u32 ) ;        svint32_t in1 = svld1_s32 ( all_mask , อินพุต + 1 * vl_u32 ) ;        svint32_t in2 = svld1_s32 ( all_mask , อินพุต + 2 * vl_u32 ) ;        svint32_t in3 = svld1_s32 ( all_mask , อินพุต + 3 * vl_u32 ) ;          svbool_t pos0 = svcmpge_n_s32 ( all_mask , in0 , 0 ) ;        svbool_t pos1 = svcmpge_n_s32 ( all_mask , in1 , 0 ) ;        svbool_t pos2 = svcmpge_n_s32 ( all_mask , in2 , 0 ) ;        svbool_t pos3 = svcmpge_n_s32 ( all_mask , in3 , 0 ) ;          in0 = svcompact_s32 ( pos0 , in0 ) ;        in1 = svcompact_s32 ( pos1 , in1 ) ;        in2 = svcompact_s32 ( pos2 , in2 ) ;        in3 = svcompact_s32 ( pos3 , in3 ) ;          svst1_s32 ( all_mask , เอาต์พุต + j , in0 ) ;        j + = svcntp_b32 ( all_mask , pos0 ) ;        svst1_s32 ( all_mask , เอาต์พุต + j , in1 ) ;        j + = svcntp_b32 ( all_mask , pos1 ) ;        svst1_s32 ( all_mask , เอาต์พุต + j , in2 ) ;        j + = svcntp_b32 ( all_mask , pos2 ) ;        svst1_s32 ( all_mask , เอาต์พุต + j , in3 ) ;        j + = svcntp_b32 ( all_mask , pos3 ) ;          อินพุต + = 4 * vl_u32 ;    }      int64_t ผม = 0 ;    นับ = endPtr - อินพุต ;      svbool_t while_mask = svwhilelt_b32 ( ผม นับ ) ;    ทำ {      svint32_t ใน = svld1_s32 ( while_mask , input + i ) ;      svbool_t positive = svcmpge_n_s32 ( while_mask ใน 0 )      svint32_t in_positive = svcompact_s32 ( บวก ใน ) ;      svst1_s32 ( while_mask , เอาต์พุต + j , in_positive ) ;      ผม + = svcntw ( ) ;      j + = svcntp_b32 ( while_mask บวก ) ;      while_mask = svwhilelt_b32 ( ผม นับ ) ;    } ในขณะที่ ( svptest_any ( svptrue_b32 ( ) while_mask ) ) ;  }