Software/Programming2016. 4. 15. 02:56

 참고 : http://blog.naver.com/jwmoon74/100157579221


1. volatile 을 사용하지 않은 변수 : 최적화가 될 수 있다. 재배치(reordering) 될 수 있다.

2. volatile 을 사용한 변수(1.5 미만) : 그 변수 자체에 대해서는 최신의 값이 읽히거나 쓰여진다.

3. volatile 을 사용한 변수(1.5 이상) : 변수 접근까지에 대해 모든 변수들의 상황이 업데이트 되고, 변수가 업데이트 된다.




1.

위와 같은 순서로 프로그램이 실행된다고 할 때(ready는 false로 초기화) volatile이 미적용된 상태에서 예상할 수 있는 문제는

1. answer와 ready의 최적화

2. 실행시간에 캐쉬된 값들이 바로 메인 메모리에 업데이트 되지 않을 수 있음


2번 문장이 실행되었는데 캐쉬만 업데이트 한 뒤, mail memory에 적용되지 않고 3번이 실행되었다면 3번에서 ready가 false로 읽어질 수 있다.


2.(1.5미만)

ready에 volatile이 적용될 경우, ready가 읽혀지거나 쓰여질 때마다 바로 업데이트 된다.

따라서 3번 문장에서 문제가 발생하지 않는다.

answer에 대하여 volatile이 적용되지 않았기에 최신의 answer(2)가 4번 문장에 전달되지 않았을 수 있다.


3.(1.5이상)

ready에 volatile이 걸렸을 경우, ready의 값이 읽혀지거나 쓰여질 때마다, 그 때까지의 쓰레드의 '모든 상태'가 업데이트 된다.

즉, thread 1의 ready가 true로 쓰여질 때,

같은 쓰레드에 있던 answer도 메인메모리에 업데이트 된다.

따라서 3번, 4번도 제대로 값이 읽어지게 된다.


Posted by 십자성군
Software/Programming2016. 4. 15. 02:43

본 자료는...


volatile이라는 정의의 의미


1.특정 최적화에 주의해라

2,.멀티 쓰레드 환경에서 주의해라


주로 C,C++이나 MCU의 레지스터를 다룰 때 1번의 의미로 사용되곤 하며

Java에서는 2번의 의미로 사용되곤 한다.


1.

옵티마이즈 기능에 의한 최적화를 시키지 않는다.


ex)


static int foo;
void bar(void)
{
    foo = 0;
 
    while (foo != 255);
}
와 같은 구문에서 최적화 옵션을 켜면, void bar내의 내용을 최적화 되어, while로 갈때는 항상 foo가 255가 아니라 0이기 때문에 

void bar_optimized(void)
{
    foo = 0;
 
    while (true);


위와 같이 된다. foo에 volatile을 적용하면


static volatile int foo;
 
void bar (void)
{
    foo = 0;
 
    while (foo != 255);
}


위와 같이 최적화에 의한 생략과정이 발생하지 않는다.

Posted by 십자성군
TMS320/F283352016. 3. 9. 00:33

DSP2833x_SysCtrl.c


위 파일에서 InitPeripheralClocks 함수가 있다.

이 함수에서는 HISPCP/LOSPCP 프리스케일 세팅뿐만 아니라 dsp28335에서 제공하는 각종 기능성 레지스터들의 기능 여부를 선택할 수 있다. 아래의 빨간 글씨 부분이다.


void InitPeripheralClocks(void)

{

   EALLOW;


// HISPCP/LOSPCP prescale register settings, normally it will be set to default values

   SysCtrlRegs.HISPCP.all = 0x0001; //HSPCLK=SYSCLKOUT/2=75MHz

   //SysCtrlRegs.LOSPCP.all = 0x0003; //LSPCLK=SYSCLKOUT/6=25MHz

   SysCtrlRegs.LOSPCP.all = 0x0002; //LSPCLK=SYSCLKOUT/4=37.5MHz


// XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT

   // XTIMCLK = SYSCLKOUT/2

   XintfRegs.XINTCNF2.bit.XTIMCLK = 1;

   // XCLKOUT = XTIMCLK/2

   XintfRegs.XINTCNF2.bit.CLKMODE = 1;

   // Enable XCLKOUT

   XintfRegs.XINTCNF2.bit.CLKOFF = 0;


// Peripheral clock enables set for the selected peripherals.

// If you are not using a peripheral leave the clock off

// to save on power.

//

// Note: not all peripherals are available on all 2833x derivates.

// Refer to the datasheet for your particular device.

//

// This function is not written to be an example of efficient code.


   SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC


   // *IMPORTANT*

   // The ADC_cal function, which  copies the ADC calibration values from TI reserved

   // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the

   // Boot ROM. If the boot ROM code is bypassed during the debug process, the

   // following function MUST be called for the ADC to function according

   // to specification. The clocks to the ADC MUST be enabled before calling this

   // function.

   // See the device data manual and/or the ADC Reference

   // Manual for more information.


   ADC_cal();



   SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0;   // I2C

   SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;   // SCI-A

   SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 1;   // SCI-B

   SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 0;   // SCI-C

   SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;   // SPI-A

   SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 0; // McBSP-A

   SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 0; // McBSP-B

   SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=0;    // eCAN-A

   SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=0;    // eCAN-B


   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the ePWM

   SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;  // ePWM1

   SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 0;  // ePWM2

   SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 0;  // ePWM3

   SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 0;  // ePWM4

   SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 0;  // ePWM5

   SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 0;  // ePWM6

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;   // Enable TBCLK within the ePWM


   SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 0;  // eCAP3

   SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 0;  // eCAP4

   SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 0;  // eCAP5

   SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 0;  // eCAP6

   SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 0;  // eCAP1

   SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 0;  // eCAP2

   SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1;  // eQEP1

   SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1;  // eQEP2


   SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0

   SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1

   SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 0; // CPU Timer 2


   SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 0;       // DMA Clock

   SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;     // XTIMCLK

   SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // GPIO input clock


   EDIS;

}

Posted by 십자성군