2010-01-26 5 views
3

저는 처음에는 컴퓨터 과학자가 아닌 엔지니어입니다. 그러니 친절하십시오. 현재 MySQL ++을 사용하는 C++ 프로그램이 있습니다. 이 프로그램은 또한 NI Visa 런타임을 통합합니다. 인터럽트 처리기 중 하나는 USB 장치에서 초당 약 200 회 데이터 (1 바이트)를 수신합니다. 원격 서버의 각 샘플에이 데이터를 타임 스탬프와 함께 저장하고 싶습니다. 이것이 가능한가? 누구든지 좋은 접근법을 추천 할 수 있습니까? 감사합니다. Michael실시간 데이터를 저장하는 MySQL ++

+0

데이터가 파열되거나 연속적입니까? –

+0

1 바이트 당 하나의 타임 스탬프는 공간과 시간의 낭비라고 생각합니다. 특히 초당 200 번입니다. USB 장치가 인터럽트 당 더 많은 바이트를 전송할 수 있는지 확인하고 싶을 수 있습니다. 인터럽트 당 64 바이트. 이렇게하면 인터럽트 코드 외부에서 더 많은 시간을 실행할 수 있습니다. –

답변

4

원격 서버에 대해 초당 200 회의 트랜잭션을 수행하는 것은 특히 이러한 트랜잭션이 작업을 수행해야하는 인터럽트 처리기의 컨텍스트에서 발생한다고 생각할 때 많이 필요하다고 생각합니다. 빨리 끝내라. 나는 당신의 인터럽트 처리기를 데이터베이스 액세스로부터 분리하는 것이 더 좋을 것이라고 생각한다. 아마도 인터럽트 처리기가 들어오는 데이터와 타임 스탬프를 일종의 메모리 내 데이터 구조 (배열, 순환 연결 목록 등)에 저장하고, 데이터 구조에서 데이터를 사용할 수있을 때까지 기다린 후 데이터베이스로 펌프하는 별도의 스레드가 있어야합니다. 그 인터럽트 처리기를 가능한 한 가늘고 결정 성있는 것으로 유지하고 싶습니다. 원격 서버에 대한 네트워크를 통한 데이터베이스 액세스가 너무 느리거나 더 나쁠 수도 있습니다. 명백한 이유가 없으므로 h * ll로 가십시오.

물론 이것은 데이터가 데이터베이스로 펌핑 될 수있는 속도보다 빠르게 들어오고 메모리 내 저장소 구조가 가득 찬 데이터 오버런 문제/문제를 야기합니다. 이로 인해 데이터가 손실 될 수 있습니다. 샘플을 떨어 뜨리면 얼마나 나쁜거야?

1

값 당 1 개의 개별 삽입으로 속도를 유지할 수는 없을 것이라고 생각하지만 충분히 큰 배치로 일괄 처리하면 모든 쿼리를 하나의 쿼리로 보낼 수 있습니다.

INSERT INTO records(timestamp, value) 
    VALUES(1, 2), (3, 4), (5, 6), [...], (399, 400); 

단지 버퍼에 타임 스탬프 값 및 푸시 버퍼 크기 (200) (또는 다른 임의의 수치)에 도달하면, SQL을 생성하고 훨씬 떨어져서 보내. sprintf로이 문자열을 구성하는 것이 너무 느려서는 안됩니다. 인터럽트 루틴이 동시에 쓰고있는 데이터 구조를 읽는 것을주의하십시오.

어떤 이유로이 SQL 생성이 너무 느리고 API (예 : 저장 프로 시저)를 사용하는 더 빠른 방법이 없다면 데이터 수집과 동시에 실행할 수 있습니다. 가장 간단한 방법은 SQL 생성을 수행하는 다른 프로세스로 소켓이나 파이프를 통해 데이터를 스트리밍하는 것입니다. 멀티 스레딩 접근법도 있지만 더 복잡하고 오류가 발생하기 쉽습니다.

+0

타임 스탬프 문제에 동의합니다. 샘플을 버퍼링하고 200 개의 값마다 하나의 타임 스탬프 만 추가합니다. 이러한 값을 저장하고 액세스 할 때 인터럽트에 문제가 발생하지 않도록 읽기 위해 어떤 저장 메커니즘을 제안 하시겠습니까? –

+0

인터럽트 문제에 대한 신뢰할 수있는 대답을 제공하려면 해당 하드웨어 및 운영 체제에 대해 잘 알고 있어야합니다. 인터럽트가 사용되는 구조 밖으로 데이터를 전송할 수있을만큼 충분히 짧은 시간 동안 인터럽트가 발생하지 않도록하는 방법이 있습니다. 또는 참조하는 두 개의 버퍼 중 하나를 전환 할 수있는 원자 적 명령어가있을 수 있지만 플랫폼에 따라 다릅니다. 이 인터럽트 루틴을 제공하는 것이 실행을 관리하는 방법을 제공하기를 희망합니다. – Kylotan

+0

2 개의 버퍼간에 전환을 시도합니다. 조언 해주셔서 감사합니다. –

0

제 생각에는 두 가지를해야합니다. 1. 데이터를 버퍼링하고 2. 버퍼 당 하나의 타임 스탬프. USB 프로토콜은 바이트 기반이 아니며 메시지 기반입니다. 메시지를 추적하는 경우 메시지에 시간을 표시하십시오.

또한 데이터베이스는 한 번에 1 바이트보다 많은 블록 또는 청크를 수신합니다. 각 트랜잭션마다 데이터베이스에 오버 헤드가 있습니다. 효율성을 측정하려면 트랜잭션의 바이트 수로 오버 헤드를 나눕니다. 큰 블록은 많은 작은 트랜잭션보다 효율적이라는 것을 알 수 있습니다.

또 다른 옵션은 데이터를 파일에 저장 한 다음 MySQL LOADFILE 함수를 사용하여 데이터베이스에 데이터를로드하는 것입니다. 또한 데이터를 버퍼에 저장 한 다음 MySQL C++ 커넥터 스트림을 사용하여 데이터를 데이터베이스에로드합니다.

+0

나는 당신이 제안한대로 1과 2를 모두 할 것입니다. 파일에 로컬로 값을 저장하는 것에 관해서는 무엇을 제안합니까? SQlite? –

+0

파일에 값을 저장하는 형식은 MySQL * LOADFILE * 함수를 참조하십시오. 필요한 파일의 형식을 알려줍니다. 프로그램 외부에서 변수를 저장하려면 Windows에서 레지스트리를 사용할 수 있습니다. 또 다른 방법은 파일에 저장하는 것입니다. XML, INI 또는 사용자 자신의 형식을 사용할 수 있습니다. SQLite를 사용하지 않았으므로 주석을 달 수는 없습니다. –

0

멀티 스레딩은 이상한 cpu 우선 순위 환경 설정이없는 한 서버 측에서 올바르게 캐시하더라도 아파트보다 더 빠르다고 보장하지 않습니다. 셰이더를 사용하고 윈도우에서 참조 값으로 패스하는 것은 어떨까요?h 타임 스탬프 여야합니다.

관련 문제