Alright, Levente! Thank you so very much! You are a generous soul & an angel! Your suggestions (the first two) worked like a charm and I have a running plugin to GF arithmetic, GFPoly arithmetic and RSDecoder arithmetic {#findErrorLocation: & #findErrorMagnitudes:errorLocations:} both plugganized. The cumulative speedup is 568% and all the hotspots changed again.
I tried to implement GFPoly>>#initializeField:coefficients: in a plugin function, but my image is crashing on startup, when standard GFs are created in GF class>>#startUp:, when each GF initializes it attempts to create a one and a zero polynomial. This would call the primitive for #initializePoly. This code can be seen in the package: CryptographyRSFECPluginsInitializeGFPoly. I am attempting to run:
(firstNonZero > coefficientsLength) ifTrue: [ mutableCoefficients := interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: 1] ifFalse: [ mutableCoefficients := interpreterProxy instantiateClass: interpreterProxy classByteArray indexableSize: (coefficientsLength - firstNonZero + 1).
The cumulative speedup is 568% and all the hotspots changed again. Here are the profiling results from just the RSFEC code alone, no RSErasure code is in the profiles. The new hotspots are, with RSFECPlugin, then without.
((128683
/ 22648) asFloat * 100) asInteger = 568%
The remaining potential plugganization relates to complex object instantiation inside the plugin functions. {#decode:twoS:, #runEuclideanAlgorithm: and #initializeField:coefficients:}. The best value for work return is to plugganize #initializeField:coefficients: at 3.3 seconds (14%)
WITH GF & GFPOLY PRIMITIVES AND DECODER
PRIMITIVES
(
3
asterix
for
in-progress plugganization)
- 22194 tallies, 22648 msec.
**Leaves** 29.1%
{
6586
ms} RSFECDecoderWithPlugin>>decode:twoS:
14.7
% {
3329
ms} RSFECGenericGFPoly
class
newField:coefficients:
7.3
% {
1646
ms} RSFECDecoderWithPlugin>>primFindErrorLocationsDegree:coefficients:result:fieldSize:
2.9
% {
654
ms} RSFECDecoderWithPlugin>>findErrorMagnitudes:errorLocations:
1.0
% {
237
ms} RSFECDecoderWithPlugin>>runEuclideanAlgorithmPoly:poly:rDegrees:
Calls to plugganized GF/GFPoly methods:
1.4% {317ms} RSFECGenericGFWithPlugin>>log:
And:
WITHOUT GF & GFPOLY PRIMITIVES - NO RSFEC PRIMITIVES
98352
tallies,
128683
msec.
**Leaves** GF arithmetic
23.4
% {
30126
ms} RSFECGenericGF>>
exp
:
13.4
% {
17229
ms} RSFECGenericGF>>addOrSubtract:by:
11.9
% {
15251
ms} RSFECGenericGF>>maskValue:
10.0
% {
12916
ms} RSFECGenericGF>>
log
:
8.6
% {
11059
ms} RSFECGenericGF>>normalizeIndex:
6.8
% {
8792
ms} RSFECGenericGF>>multiply:by: GFPoly arithmetic
2.7
% {
3529
ms} RSFECGenericGFPoly>>evaluateAt:
2.1
% {
2715
ms} RSFECGenericGFPoly>>addOrSubtractPoly:
2.0
% {
2578
ms} RSFECGenericGFPoly>>multiplyByMonomialDegree:coefficient:
--- Kindly, Robert
On 6/3/21 8:43 PM, Levente Uzonyi wrote:
Hi Robert,
I see the following potential causes:
In #findErrorLocationsDegree:coefficients:count:fieldSize:result: the return value in ambiguous. You make the primitive fail if not enough errors are found. But after the send, you don't check for failure but simply send #methodReturnReceiver. Instead, you should either check for primitive failure after the send or make #findErrorLocationsDegree:coefficients:count:fieldSize:result: return boolean value: the method was successful or not. E.g. when numErrors = 1, return true, in the other branch, return e = numErrors. (If slang doesn't support boolean types, just use 0 and 1). In the actual primitive method, check for the value returned by that method and fail the primitive when needed. Once the primitive has failed, you ought to return from it. I see the above pattern in other methods too (marking the primitive as failed in a not-top-level method without checking for failure outside). Those need to be fixed as well.
Another potential issue I see is that the validation of the arguments is not complete. E.g.: #stackIntegerValue: may have already set the primitive to failed if the argument was not an integer. So, before continuing, that has to be checked.
Another possible but unlikely problem is that you assume that both result and coefficients have at least one field. But that may not be true which can result in segfaults.
Levente