-
Type:
Enhancement
-
Resolution: Unresolved
-
Priority:
P4
-
Affects Version/s: 9, 9.0.1, 10
-
Component/s: hotspot
-
x86_64
-
linux
A DESCRIPTION OF THE REQUEST :
If a Float.isInfinite is in a loop it does not get vectorized. The same behaviour hapens when Float.POSITIVE_INFINITY or Float.NEGATIVE_INFINITY are used directly.
See example code:
private void zeroIfInfiniteInlined(float[] samples){
for (int i = 0; i < samples.length; i++) {
if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
samples[i] = 0.0f;
}
}
}
it could generate vector flags which would then be applied to a store.
JUSTIFICATION :
The code as above is pretty common in HPC, often followed by more complex computation. It is important that this call works corectly and fast. Vectorizing it can help.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1. Generate mask for 4,8,16 elements (depending on AVX-128,AVX-256,AVX-512)
2. If mask is not zero, store with mask.
ACTUAL -
Scalar instructions are used. Loop is not vectorized.
---------- BEGIN SOURCE ----------
class IsInfinity {
private void zeroIfInfiniteInlined(float[] samples){
for (int i = 0; i < samples.length; i++) {
if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
samples[i] = 0.0f;
}
}
}
private void zeroIfInfinite(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (Float.isInfinite(samples[i])) {
samples[i] = 0.0f;
}
}
}
private void zeroIfNaN(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (Float.isNaN(samples[i])) {
samples[i] = 0.0f;
}
}
}
private void zeroIfNaNInlined(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (samples[i]!=samples[i]) {
samples[i] = 0.0f;
}
}
}
public static void main(String[] argv) throws Exception {
float samples[] = new float[4000];
for (int i=0;i<samples.length;i++){
samples[i] = i;
}
IsInfinity inf = new IsInfinity();
for (int i=0;i<10000;i++){
inf.zeroIfInfinite(samples);
inf.zeroIfInfiniteInlined(samples);
inf.zeroIfNaN(samples);
inf.zeroIfNaNInlined(samples);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None.
If a Float.isInfinite is in a loop it does not get vectorized. The same behaviour hapens when Float.POSITIVE_INFINITY or Float.NEGATIVE_INFINITY are used directly.
See example code:
private void zeroIfInfiniteInlined(float[] samples){
for (int i = 0; i < samples.length; i++) {
if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
samples[i] = 0.0f;
}
}
}
it could generate vector flags which would then be applied to a store.
JUSTIFICATION :
The code as above is pretty common in HPC, often followed by more complex computation. It is important that this call works corectly and fast. Vectorizing it can help.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1. Generate mask for 4,8,16 elements (depending on AVX-128,AVX-256,AVX-512)
2. If mask is not zero, store with mask.
ACTUAL -
Scalar instructions are used. Loop is not vectorized.
---------- BEGIN SOURCE ----------
class IsInfinity {
private void zeroIfInfiniteInlined(float[] samples){
for (int i = 0; i < samples.length; i++) {
if (samples[i] == Float.POSITIVE_INFINITY || samples[i] == Float.NEGATIVE_INFINITY){
samples[i] = 0.0f;
}
}
}
private void zeroIfInfinite(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (Float.isInfinite(samples[i])) {
samples[i] = 0.0f;
}
}
}
private void zeroIfNaN(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (Float.isNaN(samples[i])) {
samples[i] = 0.0f;
}
}
}
private void zeroIfNaNInlined(float[] samples) {
for (int i = 0; i < samples.length; i++) {
if (samples[i]!=samples[i]) {
samples[i] = 0.0f;
}
}
}
public static void main(String[] argv) throws Exception {
float samples[] = new float[4000];
for (int i=0;i<samples.length;i++){
samples[i] = i;
}
IsInfinity inf = new IsInfinity();
for (int i=0;i<10000;i++){
inf.zeroIfInfinite(samples);
inf.zeroIfInfiniteInlined(samples);
inf.zeroIfNaN(samples);
inf.zeroIfNaNInlined(samples);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None.