2010-01-17 2 views
7

시스템 드라이브 Mac OS X이 켜져 있는지 여부를 확인하기위한 신뢰성 있고 신속한 결정적 방법 (아니요 벤치 마크가)이 있습니까?Mac OS X에서 SSD를 감지하는 방법은 무엇입니까?

디스크가 병렬 액세스를 얼마나 잘 처리하는지 다른 지표가 있습니까? 디스크 바인딩 작업에 내 프로그램에서 사용할 스레드 수를 조정하려고합니다.

원시 속도 나 탐색 시간에는 관심이 없습니다. 어떤 유형의 액세스 (직렬 또는 병렬) 만 드라이브보다 빠릅니다. 내 프로그램 사용자가 iSCSI 또는 RAID를 사용할 것으로 기대하지는 않습니다. SSD가 필자의 초점이며, 그 밖의 것은 SSD의 장점이다.

Device CharacteristicsIOAHCIBlockStorageDevice이이 정보를 포함합니다. 프로그래밍 방식으로 어떻게 읽을 수 있습니까?

match = IOBSDNameMatching(kIOMasterPortDefault,0,"disk0s2"); 
IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iterator); 
while(entry = IOIteratorNext(iterator)) { 
    do { 
    entry = IORegistryEntryGetParentEntry(nextMedia, kIOServicePlane, &entry); 
    dict = IORegistryEntryCreateCFProperty(nextMedia, 
      CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, 0); 
    [dict objectForKey:CFSTR(kIOPropertyMediumTypeKey)]; 
    } 
    while(!dict && entry); 
} 

편집 (다음 의사입니다) :


지금까지 내가 알아 낸 것 그것은 이렇게되면 Here's complete source code. 인텔 SSD 및 OCZ 버텍스에서 작동하는지 확인했습니다.

+0

참조 http://stackoverflow.com/q/908188/545127 – Raedwald

답변

5

그런 종류의 정보를 얻으려면 IOKit을 사용하는 것이 가장 좋습니다. 당신은 그 중 일부를 시도 할 수 있습니다

ioreg 명령 행 도구 또는 IORegistryExplorer를 사용하는 기능입니다.


다음은 몇 가지 코드입니다. 그것은 RAID가 아니고 파티션이 아닌 모든 하드 드라이브를 가져옵니다. 이것은 당신이 원하는 것이 아니지만, 당신을 시작할 수 있습니다.

#import "TWDevice.h" 

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <errno.h> 
#include <paths.h> 
#include <sys/param.h> 
#include <IOKit/IOKitLib.h> 
#include <IOKit/IOBSD.h> 
#include <IOKit/storage/IOMedia.h> 
#include <CoreFoundation/CoreFoundation.h> 
#include <IOKit/Kext/KextManager.h> 


@implementation TWDevice 

@synthesize name, devicePath, size, blockSize, writable, icon; 

+ (NSArray *)allDevices { 
    // create matching dictionary 
    CFMutableDictionaryRef classesToMatch; 
    classesToMatch = IOServiceMatching(kIOMediaClass); 
    if (classesToMatch == NULL) { 
     [NSException raise:@"TWError" format:@"Classes to match could not be created"]; 
    } 

    // get iterator of matching services 
    io_iterator_t mediaIterator; 
    kern_return_t kernResult; 
    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, 
                     classesToMatch, 
                     &mediaIterator); 

    if (kernResult != KERN_SUCCESS) { 
     [NSException raise:@"TWError" format:@"Matching services did not succed."]; 
    } 

    // iterate over all found medias 
    io_object_t nextMedia; 
    NSMutableArray *detectedDevices = [NSMutableArray array]; 
    while (nextMedia = IOIteratorNext(mediaIterator)) { 
     NSMutableDictionary *properties; 
     kernResult = IORegistryEntryCreateCFProperties(nextMedia, 
                        (CFMutableDictionaryRef *)&properties, 
                        kCFAllocatorDefault, 0); 

     if (kernResult != KERN_SUCCESS) { 
      [NSException raise:@"TWError" format:@"Getting properties threw error."]; 
     } 

     // is it a whole device or just a partition? 
     if ([[properties valueForKey:@"Whole"] boolValue] && 
      ![[properties valueForKey:@"RAID"] boolValue]) { 
      TWDevice *device = [[[TWDevice alloc] init] autorelease]; 

      device.devicePath = [NSString stringWithFormat:@"%sr%@", _PATH_DEV, [properties valueForKey:@"BSD Name"]]; 
      device.blockSize = [[properties valueForKey:@"Preferred Block Size"] unsignedLongLongValue]; 
      device.writable = [[properties valueForKey:@"Writable"] boolValue]; 
      device.size = [[properties valueForKey:@"Size"] unsignedLongLongValue]; 

      io_name_t name; 
      IORegistryEntryGetName(nextMedia, name); 
      device.name = [NSString stringWithCString:name encoding:NSASCIIStringEncoding]; 

      … 

      [detectedDevices addObject:device]; 
     } 

     // tidy up 
     IOObjectRelease(nextMedia); 
     CFRelease(properties); 
    } 
    IOObjectRelease(mediaIterator); 

    return detectedDevices; 
} 

@end 
+0

@ porneL : 몇 가지 코드를 추가했습니다. 도움이됩니다. –

+0

감사합니다. 그것은 매우 도움이되었습니다. 그것 없이는 IOKit C++ API를 무의식으로 파고들 수 있습니다. – Kornel

+0

@porneL : 네가 알아 낸 것 같아. 이 질문에 더 이상 도움이 필요하지 않다고 생각합니다. 맞습니까? –

6

실제로, 나는 당신이 더 정확하게 당신의 질문에 답하기 때문에 당신이 벤치마킹 루트를 따라 가야한다고 생각합니다. 정말로 디스크가 SSD 일 것이라는 것을주의하십시오, 당신은 단지 디스크가 정말로 빠르다는 것을 신경 써야합니다. 사용자가 빠른 RAID 설정 또는 파이버 채널 배열을 사용 중이거나 iSCSI를 사용하고 있다면 어떻게 될까요?

그냥

+2

"빠른"기준선 측정 값이 없습니다. 두 가지 벤치 마크를 실행하고 비교해야합니다. 신뢰할 수있는 벤치마킹에 소요되는 시간은 더 나은 전략을 선택하여 절약 한 시간보다 오래 걸릴 수 있습니다. 짧은 벤치 마크는 신뢰할 수 없으므로 캐시, 대기 시간 등을 고려하는 것이 까다로울 수 있습니다. 저는 빠르고 결정 론적 인 해결책을 찾고 있습니다. SSD 이외의 것을 지원할 필요는 없습니다. – Kornel

+1

이 정도면 충분 하겠지만, Windows OS가 취하는 접근 방식이라는 것을 알려 드릴 것입니다. 약간의 통계 만 보게되면 매우 쉽게 볼 수 있습니다. 2 개의 테스트를 실행하고, 하나는 역 순차 읽기 (즉, 섹터 5, 4, 3, 2 등)를 수행 한 다음 임의의 섹터를 읽은 두 번째 테스트를 실행합니다.기본적으로 분산이 동일하면 SSD가 있습니다. 기계적 디스크에서 크게 달라질 것입니다 –

0

스레드 수를 드라이브 기본은/dev/diskX에서 임의 부문의 무리를 읽고 사용자의 요구 사항을 충족하는 경우 당신은 "빠른"로 취급 할 수 있습니까? 1은 디스크, SSD, RAID를 압도합니다. 디스크가 느리며 프로세서가 빠릅니다. 운영체제는 헤드의 움직임을 최소화하기 위해 디스크 요청을 여하튼 재정렬 할 것입니다.

+0

적어도 Windows 및 Linux에서는 OS가 SSD에 대한 디스크 요청을 재정렬하지 않습니다. –

+1

제 경험으로 볼 때 OS X는 디스크 액세스를 관리하는 작업을 제대로 수행하지 못합니다 (병렬 액세스로 인해 효율적이기보다는 쓰레기가 발생 함). 접속하다). SSD에 액세스하는 다중 I/O 바인딩 스레드는 더 빠릅니다. CPU 오버 헤드가 포함되어 있기는하지만 속도는 더 빠릅니다. – Kornel