linux C 프로그래밍에서 캐쉬가 아닌 메모리에서 읽어오게 하는 방법.

trymp의 이미지

멀티쓰래드 프로그래밍에서 char *ptr 이라는 포인터가 있을때,

ptr 이 여러 쓰래드에서 갱신되고 읽을수가 있는데, lock API 나 volatile f같은 키워드를

사용하지 않고 레지스터가 아닌 메모리에서 읽어오고 싶습니다.

volatile 키워드를 쓰니 너무 여러군데서 warning 이 발생해서..ㅠㅠ

ptr 포인터 변수를 읽어올때 레지스터에서 읽어오는게 아니라 메모리에서 읽어오고

쓸때도 메모리에 항상 업데이트 할수 있는 방법을 찾고 있습니다.

알려주시면 감사하겠습니다.

AustinKim의 이미지

궁금해하시는 부분을 리눅스 시스템 저수준 함수로 설정을 할 수 있을 지 의문입니다.
아마, 커널 공간에서 페이지 메모리를 UNCACHED 정책을 적용해 할당 받으면 될 것 같은데요.

아래 매크로 선언부를 참고하시면 좋겠습니다.

https://elixir.bootlin.com/linux/v4.19.30/source/arch/arm/mm/mmu.c
#define CPOLICY_UNCACHED 0
#define CPOLICY_BUFFERED 1
#define CPOLICY_WRITETHROUGH 2
#define CPOLICY_WRITEBACK 3
#define CPOLICY_WRITEALLOC 4

리눅스 커널의 캐시 정책에 대해서는 아래 링크의 내용을 참고하세요.
http://jake.dothome.co.kr/cache1/

(개인블로그)
http://rousalome.egloos.com

라스코니의 이미지

여러 쓰레드에서 갱신되고 있다면 캐쉬나 volatile의 문제가 아닙니다.
mutex를 걸고 사용하셔야 됩니다. 그런데 lock API를 쓰지 않고 읽어오고 싶다고 하셨는데... 솔직히 방법이 떠오르지 않네요.

Necromancer의 이미지

굳이 하시겠다면 어셈블리 레벨로 접근하시면 됩니다. x86은 movnt가 있네요.
이런 명령 없으면 윗분이 말씀하신 no-cache type의 page를 생성해서 그곳에 변수 만들어 쓰거나, 쓴 직후 일일이 cache 동기화하는 명령을 실행하는거 외는 없습니다.

https://stackoverflow.com/questions/37889896/intel-instructions-for-access-to-memory-which-skips-cache

OS에서 제공하는 mutex, semaphone가 이들을 쓰기 편하게 만든겁니다. 어느 CPU든지 간에 똑같은 효과 내게요.

Written By the Black Knight of Destruction

Hyun의 이미지

ddr cache 의 문제가 아니라 컴파일러 옵티마이즈에 대한 변수의 register caching 이 아닌가요?
그렇다면, volatile 을 쓰는 수 밖에 없어보이는데..


나도 세벌식을 씁니다
bushi의 이미지

register 대신 memory 이용을 하도록 컴파일러의 최적화 과정을 확실히 방해하고 싶다면 volatile 이 가장 확실합니다.

lockless 와는 약간 다른 얘기지만,
1. stdatomic 은 libc 혹은 libstdc++ 에 있습니다. https://en.cppreference.com/w/c/atomic
2. GCC 의 것은 https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
3. GCC 에서 Hyun 님이 언급하신 CPU 별 instrinsic 은 https://gcc.gnu.org/onlinedocs/gcc/Target-Builtins.html

만에 하나, 정말로 cache 를 쓰고 싶지 않다는 질문이라면 linux 에선,
open("/dev/mem", O_DSYNC|O_RDWR),
mmap(PROT_READ|PROT_WRITE, MAP_PRIVATE)
정도로 메모리 할당 받아서 변수를 보관하는 방법을 시도해 볼 수는 있습니다. https://elixir.bootlin.com/linux/v5.7.8/source/drivers/char/mem.c#L283

익명 사용자의 이미지

멀티스레드 환경에서 thread간 data race가 발생할 수 있다면 정답은 atomic types입니다.
volatile를 그런 상황에서 쓰는 건 권장할 만한 일이 아니에요.

https://en.cppreference.com/w/c/language/atomic

Quote:
Objects of atomic types are the only objects that are free from data races, that is, they may be modified by two threads concurrently or modified by one and read by another.

https://en.cppreference.com/w/c/language/volatile

Quote:
Note that volatile variables are not suitable for communication between threads; they do not offer atomicity, synchronization, or memory ordering. A read from a volatile variable that is modified by another thread without synchronization or concurrent modification from two unsynchronized threads is undefined behavior due to a data race.

====

Quote:
volatile 키워드를 쓰니 너무 여러군데서 warning 이 발생해서..ㅠㅠ

지금 귀하의 목표가 그저 컴파일러의 warning을 없애는 것인가요,
아니면 올바른 멀티스레드 프로그램을 만드는 것인가요?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.