Using Inline::Pdlpp, it performs comparably with _longest_c1, use this diff to the above:
--- collatz.orig 2024-07-27 23:53:49.665967800 +0100 +++ collatz 2024-07-28 03:21:55.085180253 +0100 @@ -119,11 +119,19 @@ return ( $number, $highest ); } +use Inline Pdlpp => 'DATA', clean_after_build => 0; +sub PDL::collatz_pdl { + PDL::_collatz_pdl_int(@_, my $n = PDL->null, my $h = PDL->null); + # Perl scalars because is across forked processes in MCE + map $_->sclr, $n, $h; +} + no warnings 'once'; #*collatz = \&collatz_longest; # choose collatz here #*collatz = \&collatz_longest_c1; # using T(x) notation - *collatz = \&collatz_longest_c2; # using compiler intrinsics +#*collatz = \&collatz_longest_c2; # using compiler intrinsics + *collatz = \&PDL::collatz_pdl; # using PDL my $m = shift || '1e7'; my ( @sizes, $chunk_size ); @@ -151,3 +159,27 @@ say "@$_" for ( sort { $a->[0] <=> $b->[0] } grep { $_->[1] == $highest } @sizes )[ 0..0 ]; + +__DATA__ +__Pdlpp__ +pp_def('collatz_pdl', + Pars => 'beg(); end(); [o]number(); [o]highest()', + GenericTypes => ['Q'], + PMCode => '', # trigger the _int but keep the Perl code in main bod +y + Code => ' + PDL_Indx i, number = 0, highest = 0; + for ( i = $end(); i >= $beg(); i-- ) { + PDL_Indx n = i, steps = 0; + /* count using the T(x) notation */ + do { + n % 2 ? ( steps += 2, n = (3 * n + 1) >> 1 ) + : ( steps += 1, n = n >> 1 ); + } while ( n != 1 ); + if ( steps >= highest ) { + number = i, highest = steps; + } + } + $number() = number; + $highest() = highest; + ', +);
It revealed a quirk to Inline::Pdlpp, which makes/loads the XS code, but drops the Perl code, so PMCode gets ignored. I've added that to the doc which will be in next release.

The most idiomatic way to get PDL to do this would be to broadcast the above operation over a higher dim that has as many things in its as cores you have, and let the PDL pthreads do their thing instead of MCE. That would have the challenge that the Collatz stuff is quite non-deterministic in processing need, which reminds me that I've meant for a while to break PDL pthreading into smaller chunks and distribute across a thread pool which would mitigate this. PRs to beat me to it very welcome!

A PDL solution doesn't work great in MCE because the outputs needed to be converted to Perl scalars to be successfully passed across forked processes.


In reply to Re: Longest Collatz using MCE::Flow, Inline::C, and GCC compiler intrinsics by etj
in thread Longest Collatz using MCE::Flow, Inline::C, and GCC compiler intrinsics by marioroy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.