peter-lawrey / Java-Thread-Affinity

Control thread affinity for Java
379 stars 77 forks source link

getAffinity: incompatible types: java.util.BitSet cannot be converted to long #47

Open shizukanaskytree opened 7 years ago

shizukanaskytree commented 7 years ago

I try to set affinity to one thread, however,

If you want to get/set the affinity directly you can do

long currentAffinity = AffinitySupport.getAffinity();
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.

I get some errors about data type.

Error:(21, 52) java: incompatible types: java.util.BitSet cannot be converted to long

Error:(22, 17) java: no suitable method found for setAffinity(long)
    method net.openhft.affinity.Affinity.setAffinity(java.util.BitSet) is not applicable
      (argument mismatch; long cannot be converted to java.util.BitSet)
    method net.openhft.affinity.Affinity.setAffinity(int) is not applicable
      (argument mismatch; possible lossy conversion from long to int)

The code

package net.openhft.affinity;
import static net.openhft.affinity.AffinityStrategies.*;
//import static net.openhft.affinity.Affinity.*;
/**
 * @author peter.lawrey
 */
public final class AffinityLockBindMainTest {
    private AffinityLockBindMainTest() {
        throw new InstantiationError( "Must not instantiate this class" );
    }

    public static void main(String... args) throws InterruptedException {
        AffinityLock al = AffinityLock.acquireLock();

        int threadId = AffinitySupport.getThreadId();
        System.out.println("threadId of main "+ threadId);

        int cpuId = Affinity.getCpu();
        System.out.println("cpuId of main: " + cpuId);

        long currentAffinity = Affinity.getAffinity();
        Affinity.setAffinity(1L << 5); // lock to CPU 5.

        try {
            // find a cpu on a different socket, otherwise a different core.
            AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET, DIFFERENT_CORE);
            new Thread(new SleepRunnable(readerLock, false), "reader").start();

            // find a cpu on the same core, or the same socket, or any free cpu.
            //AffinityLock writerLock = readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY);
            //new Thread(new SleepRunnable(writerLock, false), "writer").start();

            Thread.sleep(200);
        } finally {
            al.release();
        }

        // allocate a whole core to the engine so it doesn't have to compete for resources.
        //al = AffinityLock.acquireCore(false);
        //new Thread(new SleepRunnable(al, true), "engine").start();

        Thread.sleep(200);
        System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());
    }

    static class SleepRunnable implements Runnable {
        private final AffinityLock affinityLock;
        private final boolean wholeCore;

        SleepRunnable(AffinityLock affinityLock, boolean wholeCore) {
            this.affinityLock = affinityLock;
            this.wholeCore = wholeCore;
        }

        public void run() {
            affinityLock.bind(wholeCore);

            int threadId = AffinitySupport.getThreadId();
            System.out.println("threadId of one SleepRunnable "+ threadId);

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                affinityLock.release();
            }
        }
    }
}
peter-lawrey commented 7 years ago

This method was changed to support systems with more than 64 cpus. Is this an example from the documentation? If so we can correct it.

On 15 Sep. 2017 07:38, "Xiaofeng Wu" notifications@github.com wrote:

I try to set affinity to one thread, however,

If you want to get/set the affinity directly you can do

long currentAffinity = AffinitySupport.getAffinity(); AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.

I get some errors about data type.

Error:(21, 52) java: incompatible types: java.util.BitSet cannot be converted to long

Error:(22, 17) java: no suitable method found for setAffinity(long) method net.openhft.affinity.Affinity.setAffinity(java.util.BitSet) is not applicable (argument mismatch; long cannot be converted to java.util.BitSet) method net.openhft.affinity.Affinity.setAffinity(int) is not applicable (argument mismatch; possible lossy conversion from long to int)

The code

package net.openhft.affinity;import static net.openhft.affinity.AffinityStrategies.;//import static net.openhft.affinity.Affinity.;/* @author peter.lawrey */public final class AffinityLockBindMainTest { private AffinityLockBindMainTest() { throw new InstantiationError( "Must not instantiate this class" ); }

public static void main(String... args) throws InterruptedException {
    AffinityLock al = AffinityLock.acquireLock();

    int threadId = AffinitySupport.getThreadId();
    System.out.println("threadId of main "+ threadId);

    int cpuId = Affinity.getCpu();
    System.out.println("cpuId of main: " + cpuId);

    long currentAffinity = Affinity.getAffinity();
    Affinity.setAffinity(1L << 5); // lock to CPU 5.

    try {
        // find a cpu on a different socket, otherwise a different core.
        AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET,

DIFFERENT_CORE); new Thread(new SleepRunnable(readerLock, false), "reader").start();

        // find a cpu on the same core, or the same socket, or any free cpu.
        //AffinityLock writerLock =

readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY); //new Thread(new SleepRunnable(writerLock, false), "writer").start();

        Thread.sleep(200);
    } finally {
        al.release();
    }

    // allocate a whole core to the engine so it doesn't have to

compete for resources. //al = AffinityLock.acquireCore(false); //new Thread(new SleepRunnable(al, true), "engine").start();

    Thread.sleep(200);
    System.out.println("\nThe assignment of CPUs is\n" +

AffinityLock.dumpLocks()); }

static class SleepRunnable implements Runnable {
    private final AffinityLock affinityLock;
    private final boolean wholeCore;

    SleepRunnable(AffinityLock affinityLock, boolean wholeCore) {
        this.affinityLock = affinityLock;
        this.wholeCore = wholeCore;
    }

    public void run() {
        affinityLock.bind(wholeCore);

        int threadId = AffinitySupport.getThreadId();
        System.out.println("threadId of one SleepRunnable "+ threadId);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            affinityLock.release();
        }
    }
}

}

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/peter-lawrey/Java-Thread-Affinity/issues/47, or mute the thread https://github.com/notifications/unsubscribe-auth/ABBU8U-t1rSozp8E5as2ejDqRuagiZplks5sihtdgaJpZM4PYjEZ .

shizukanaskytree commented 7 years ago

Dear Peter,

Yes, I follow the tutorial in https://github.com/OpenHFT/Java-Thread-Affinity/README.md

The file path of the test Java program is in affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java

The purpose of my modification is that I want to bind main thread to one specific CPU.

But I don't know how to do it right now. I am not sure how to implement it since I haven't fully understand funciton usage like affinityLock.bind(wholeCore);.


What I want to do is that, for example, I would like to do a very simple single thread implementation.

Could you tell me how to do that or could you please add one more simple implementation about how to set affinity of main thread of a program. Thanks!

import java.util.ArrayDeque;

public class Runner {
    public static void main(String[] args) throws InterruptedException {
        ArrayDeque<byte[]> deque = new ArrayDeque<byte[]>(); // define a deque
        int objectSize = 1024;

        for(int i = 0; i < 5000; i++){
            for(int j = 0; j < 100; j++){
                deque.addLast(new byte[objectSize]);  // put something into it
            }

            for(int j = 0; j < 10; j++){
                deque.removeLast();  // get something out
            }
        }
    }
}

So I try to comment writer and engine threads initialization except reader in AffinityLockBindMain.java, and set affinity by using following the tutorial

If you want to get/set the affinity directly you can do

long currentAffinity = AffinitySupport.getAffinity();   // (1)
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.// (2)

And I find that (1) and (2) are deprecated in AffinitySupport.java. They are actually in the Affinity.java in /affinity/src/main/java/net/openhft/affinity/Affinity.java


Appendix of Code :

package net.openhft.affinity;
import java.util.BitSet;

import static net.openhft.affinity.AffinityStrategies.*;
//import static net.openhft.affinity.Affinity.*;
/**
 * @author peter.lawrey
 */
public final class AffinityLockBindMainTest {
    private AffinityLockBindMainTest() {
        throw new InstantiationError( "Must not instantiate this class" );
    }

    public static void main(String... args) throws InterruptedException {
        AffinityLock al = AffinityLock.acquireLock();

        int threadId = AffinitySupport.getThreadId();
        System.out.println("threadId of main "+ threadId);

        int cpuId = Affinity.getCpu();
        System.out.println("cpuId of main: " + cpuId);

        // current cpu bitmap
        BitSet currentAffinity = Affinity.getAffinity();
        // print the bitmap
        StringBuilder s = new StringBuilder();
        for( int i = 0; i < currentAffinity.length();  i++ )
        {
            s.append( currentAffinity.get( i ) == true ? 1: 0 );
        }
        System.out.println( s );

        //Affinity.setAffinity( 1L << 5 ); // lock to CPU 5.

        try {
            // find a cpu on a different socket, otherwise a different core.
            AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET, DIFFERENT_CORE);
            new Thread(new SleepRunnable(readerLock, false), "reader").start();

            // find a cpu on the same core, or the same socket, or any free cpu.
            //AffinityLock writerLock = readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY);
            //new Thread(new SleepRunnable(writerLock, false), "writer").start();

            Thread.sleep(200);
        } finally {
            al.release();
        }

        // allocate a whole core to the engine so it doesn't have to compete for resources.
        //al = AffinityLock.acquireCore(false);
        //new Thread(new SleepRunnable(al, true), "engine").start();

        Thread.sleep(200);
        System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());
    }

    static class SleepRunnable implements Runnable {
        private final AffinityLock affinityLock;
        private final boolean wholeCore;

        SleepRunnable(AffinityLock affinityLock, boolean wholeCore) {
            this.affinityLock = affinityLock;
            this.wholeCore = wholeCore;
        }

        public void run() {
            affinityLock.bind(wholeCore);

            int threadId = AffinitySupport.getThreadId();
            System.out.println("threadId of one SleepRunnable "+ threadId);

            // current cpu bitmap
            BitSet currentAffinity = Affinity.getAffinity();
            // print the bitmap
            StringBuilder s = new StringBuilder();
            for( int i = 0; i < currentAffinity.length();  i++ )
            {
                s.append( currentAffinity.get( i ) == true ? 1: 0 );
            }
            System.out.println( s );

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                affinityLock.release();
            }
        }
    }
}